bitkeeper revision 1.339.1.1 (3f108aff8cNSEyxZFIWHZ-zZtSTT2w)
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 12 Jul 2003 22:26:07 +0000 (22:26 +0000)
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>
Sat, 12 Jul 2003 22:26:07 +0000 (22:26 +0000)
Many files:
  new file
  Clean up dom0 proc interfaces. Implemented ioremap and /dev/mem.
.del-dom0_block.c~63815c1974691c1c:
  Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c
.del-sched_ops.c~20807e5c2ed6b51:
  Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c
.del-xi_list~49abab167156959:
  Delete: tools/internal/xi_list
.del-xl_physdisk_proc.c~49451bc26a40fcb2:
  Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
.del-mmu.h~6bc56547519b6f96:
  Delete: xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h
.del-dom0.h~6fb656bb4a0c52e1:
  Delete: xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h
.del-dom0_ops.h~fb19960d77217740:
  Delete: tools/internal/dom0_ops.h
.del-dom0_ops.h~5c52b016e619bd2d:
  Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
.del-dom0_memory.c~c72c6e5f7fd65d38:
  Delete: xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c
.del-direct_map.c~d2fedc686b334f2a:
  Delete: xenolinux-2.4.21-sparse/arch/xeno/mm/direct_map.c
direct_map.c:
  Rename: xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c -> xenolinux-2.4.21-sparse/arch/xeno/mm/direct_map.c

63 files changed:
.rootkeys
tools/control/src/org/xenoserver/control/CommandVbdCreate.java
tools/control/src/org/xenoserver/control/CommandVbdCreatePhysical.java
tools/control/src/org/xenoserver/control/CommandVbdList.java
tools/internal/Makefile
tools/internal/dom0_defs.h
tools/internal/dom0_ops.h [deleted file]
tools/internal/mem_defs.h
tools/internal/xi_build.c
tools/internal/xi_create.c
tools/internal/xi_destroy.c
tools/internal/xi_list [deleted file]
tools/internal/xi_list.c [new file with mode: 0644]
tools/internal/xi_phys_grant.c
tools/internal/xi_phys_probe.c
tools/internal/xi_phys_revoke.c
tools/internal/xi_sched_domain.c [new file with mode: 0644]
tools/internal/xi_sched_global.c [new file with mode: 0644]
tools/internal/xi_start.c
tools/internal/xi_stop.c
tools/internal/xi_usage.c [new file with mode: 0644]
tools/internal/xi_vifinit
xen/common/dom0_ops.c
xen/common/domain.c
xen/common/kernel.c
xen/common/network.c
xen/include/hypervisor-ifs/dom0_ops.h
xen/include/hypervisor-ifs/network.h
xen/include/xeno/sched.h
xenolinux-2.4.21-sparse/arch/xeno/Makefile
xenolinux-2.4.21-sparse/arch/xeno/config.in
xenolinux-2.4.21-sparse/arch/xeno/defconfig
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/Makefile
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c [deleted file]
xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/Makefile
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c [deleted file]
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c [deleted file]
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h [deleted file]
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c [deleted file]
xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c
xenolinux-2.4.21-sparse/arch/xeno/kernel/process.c
xenolinux-2.4.21-sparse/arch/xeno/mm/Makefile
xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c [deleted file]
xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c
xenolinux-2.4.21-sparse/drivers/char/mem.c [new file with mode: 0644]
xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h [deleted file]
xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h
xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h [deleted file]
xenolinux-2.4.21-sparse/include/asm-xeno/mmu_context.h
xenolinux-2.4.21-sparse/include/asm-xeno/multicall.h
xenolinux-2.4.21-sparse/include/asm-xeno/pgalloc.h
xenolinux-2.4.21-sparse/include/asm-xeno/pgtable.h
xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h [new file with mode: 0644]
xenolinux-2.4.21-sparse/include/asm-xeno/segment.h
xenolinux-2.4.21-sparse/mkbuildtree
xenolinux-2.4.21-sparse/mm/memory.c
xenolinux-2.4.21-sparse/mm/mprotect.c [new file with mode: 0644]
xenolinux-2.4.21-sparse/mm/mremap.c
xenolinux-2.4.21-sparse/mm/vmalloc.c [new file with mode: 0644]

index 037fbbc3f8f917887ef96d00f5e3d7cfd1b86116..9d6ec81b45d3ab8ea086f6e975ce4e589900afc3 100644 (file)
--- a/.rootkeys
+++ b/.rootkeys
 3eb781fcabCKRogwxJA3-jJKstw9Vg tools/control/xenctl.xml
 3eb781fdl4lXWYZzmqDDUAYhAThRqQ tools/internal/Makefile
 3eb781fdc539MQQm47rYRCCR3N5i-Q tools/internal/dom0_defs.h
-3ee609b3Yr4aggmLSKmhiIzT8-nURA tools/internal/dom0_ops.h
 3eb781fdKiQbgozBsgs_zzJQ9ubehw tools/internal/mem_defs.h
 3ec61e1bJCeJJu0SsptmDpA1xKvwvw tools/internal/rpm.spec
 3eb781fdgbSkh2O6JQS-65Dz4n0ItQ tools/internal/xi_build.c
 3eb781fdW1SAyiaC4mTsXq_9fRHh-A tools/internal/xi_create.c
 3eb781fdcJ0fF7rWfzAOArW-x4-gwA tools/internal/xi_destroy.c
 3ec43c5dmQxGDvgJJXbV1yLxT30Y1A tools/internal/xi_helper
-3eb83c3bZeECmphOKOJxSu4Lo1LpBw tools/internal/xi_list
+3f108ad5wQm0ZaQ4GXFoUhH1W1aW9w tools/internal/xi_list.c
 3f0458aaXhD8BQAggO81gv30RQ-ifA tools/internal/xi_phys_grant.c
 3f0458aaJHmlzkDwf0qxEzAcjX55sg tools/internal/xi_phys_probe.c
 3f0458aaVAbFSwptQbQAnDOiZlwQ3w tools/internal/xi_phys_revoke.c
+3f108adb2b5OkKL6-faG3lMiOYDf_w tools/internal/xi_sched_domain.c
+3f108ade1v8weyh1sKx890VTd240Hw tools/internal/xi_sched_global.c
 3eb781fd8oRfPgH7qTh7xvgmwD6NgA tools/internal/xi_start.c
 3eb781fd0Eo9K1jEFCSAVzO51i_ngg tools/internal/xi_stop.c
+3f108ae2to5nHRRXfvUK7oxgjcW_yA tools/internal/xi_usage.c
 3eb781fd7211MZsLxJSiuy7W4KnJXg tools/internal/xi_vifinit
 3ddb79bcbOVHh38VJzc97-JEGD4dJQ xen/Makefile
 3ddb79bcCa2VbsMp7mWKlhgwLQUQGA xen/README
 3e5a4e65pP5spJErBW69pJxSSdK9RA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.c
 3e67f822FOPwqHiaRKbrskgWgoNL5g xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_block.h
 3e677190SjkzJIvFifRVeYpIZOCtYA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_ide.c
-3f045897EIYU5l5jxFBpeF1Z0ZOTwA xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
 3e677193nOKKTLJzcAu4SYdbZaia8g xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_scsi.c
 3e676eb5RXnHzSHgA1BvM0B1aIm4qg xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment.c
 3e5d129aDldt6geU2-2SzBae34sQzg xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_segment_proc.c
 3e5a4e65G3e2s0ghPMgiJ-gBTUJ0uQ xenolinux-2.4.21-sparse/arch/xeno/drivers/console/Makefile
 3e5a4e651TH-SXHoufurnWjgl5bfOA xenolinux-2.4.21-sparse/arch/xeno/drivers/console/console.c
 3e5a4e656nfFISThfbyXQOA6HN6YHw xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/Makefile
-3e5a4e65Cc7io-vynYob10SlqXTjAQ xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c
 3e5a4e65BXtftInNHUC2PjDfPhdZZA xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_core.c
-3e5a4e65uXAx05p6B1-HU2tijuw8qA xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c
-3e5a4e65EOOLlPwXnhSuX-iVdWLmnA xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
-3e6dba59C8o0kBks7UZ4IW_FY853Aw xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c
 3e5a4e65gfn_ltB8ujHMVFApnTTNRQ xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/vfr.c
 3e5a4e65gZBRBB6RsSVg1c9iahigAw xenolinux-2.4.21-sparse/arch/xeno/drivers/network/Makefile
 3e5a4e65ZxKrbFetVB84JhrTyZ1YuQ xenolinux-2.4.21-sparse/arch/xeno/drivers/network/network.c
 3e5a4e6637ZDk0BvFEC-aFQs599-ng xenolinux-2.4.21-sparse/arch/xeno/lib/delay.c
 3e5a4e66croVgpcJyJuF2ycQw0HuJw xenolinux-2.4.21-sparse/arch/xeno/mm/Makefile
 3e5a4e66l8Q5Tv-6B3lQIRmaVbFPzg xenolinux-2.4.21-sparse/arch/xeno/mm/fault.c
-3e5a4e66TyNNUEXkr5RxqvQhXK1MQA xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c
 3e5a4e668SE9rixq4ahho9rNhLUUFQ xenolinux-2.4.21-sparse/arch/xeno/mm/hypervisor.c
 3e5a4e661gLzzff25pJooKIIWe7IWg xenolinux-2.4.21-sparse/arch/xeno/mm/init.c
 3f0bed43UUdQichXAiVNrjV-y2Kzcg xenolinux-2.4.21-sparse/arch/xeno/mm/ioremap.c
 3e5a4e66qRlSTcjafidMB6ulECADvg xenolinux-2.4.21-sparse/arch/xeno/vmlinux.lds
 3ea53c6em6uzVHSiGqrbbAVofyRY_g xenolinux-2.4.21-sparse/drivers/block/genhd.c
 3e5a4e66mrtlmV75L1tjKDg8RaM5gA xenolinux-2.4.21-sparse/drivers/block/ll_rw_blk.c
+3f108aeaLcGDgQdFAANLTUEid0a05w xenolinux-2.4.21-sparse/drivers/char/mem.c
 3e5a4e66rw65CxyolW9PKz4GG42RcA xenolinux-2.4.21-sparse/drivers/char/tty_io.c
 3e5a4e669uzIE54VwucPYtGwXLAbzA xenolinux-2.4.21-sparse/fs/exec.c
 3f05a939l8s0eQb_fpMvYiI06cTGlA xenolinux-2.4.21-sparse/fs/partitions/Config.in
 3f05a939_I9vPADPgyVBwUDUxtoeOQ xenolinux-2.4.21-sparse/fs/partitions/xeno.h
 3e5a4e66wbeCpsJgVf_U8Jde-CNcsA xenolinux-2.4.21-sparse/include/asm-xeno/bugs.h
 3e5a4e66HdSkvIV6SJ1evG_xmTmXHA xenolinux-2.4.21-sparse/include/asm-xeno/desc.h
-3f0c3721E5WAnbeoPp7PE35J_Ndxaw xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h
 3e5a4e66SYp_UpAVcF8Lc1wa3Qtgzw xenolinux-2.4.21-sparse/include/asm-xeno/fixmap.h
 3e5a4e67w_DWgjIJ17Tlossu1LGujQ xenolinux-2.4.21-sparse/include/asm-xeno/highmem.h
 3e5a4e67YtcyDLQsShhCfQwPSELfvA xenolinux-2.4.21-sparse/include/asm-xeno/hw_irq.h
 3e5a4e677VBavzM1UZIEcH1B-RlXMA xenolinux-2.4.21-sparse/include/asm-xeno/hypervisor.h
 3e5a4e673p7PEOyHFm3nHkYX6HQYBg xenolinux-2.4.21-sparse/include/asm-xeno/irq.h
 3ead095db_LRUXnxaqs0dA1DWhPoQQ xenolinux-2.4.21-sparse/include/asm-xeno/keyboard.h
-3e5a4e67zoNch27qYhEBpr2k6SABOg xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h
 3e5a4e678ddsQOpbSiRdy1GRcDc9WA xenolinux-2.4.21-sparse/include/asm-xeno/mmu_context.h
 3e7270deQqtGPSnFxcW4AvJZuTUWfg xenolinux-2.4.21-sparse/include/asm-xeno/multicall.h
 3e5a4e67mnQfh-R8KcQCaVo2Oho6yg xenolinux-2.4.21-sparse/include/asm-xeno/page.h
 3e5a4e67uTYU5oEnIDjxuaez8njjqg xenolinux-2.4.21-sparse/include/asm-xeno/pgalloc.h
 3e5a4e67X7JyupgdYkgDX19Huj2sAw xenolinux-2.4.21-sparse/include/asm-xeno/pgtable-2level.h
 3e5a4e67gr4NLGtQ5CvSLimMYZlkOA xenolinux-2.4.21-sparse/include/asm-xeno/pgtable.h
+3f108af1qNv8DVSGPv4zpqIU1txCkg xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h
 3e5a4e676uK4xErTBDH6XJREn9LSyg xenolinux-2.4.21-sparse/include/asm-xeno/processor.h
 3e5a4e67AJPjW-zL7p-xWuA6IVeH1g xenolinux-2.4.21-sparse/include/asm-xeno/ptrace.h
 3e5a4e68uJz-xI0IBVMD7xRLQKJDFg xenolinux-2.4.21-sparse/include/asm-xeno/segment.h
 3eba8f878XjouY21EkQBXwYBsPsipQ xenolinux-2.4.21-sparse/lndir-rel
 3e6e7c1efbQe93xCvOpOVCnXTMmQ5w xenolinux-2.4.21-sparse/mkbuildtree
 3e5a4e68GxCIaFH4sy01v1wjapetaA xenolinux-2.4.21-sparse/mm/memory.c
+3f108af5VxPkLv13tXpXgoRKALQtXQ xenolinux-2.4.21-sparse/mm/mprotect.c
 3e5a4e681xMPdF9xCMwpyfuYMySU5g xenolinux-2.4.21-sparse/mm/mremap.c
 3e5a4e683HKVU-sxtagrDasRB8eBVw xenolinux-2.4.21-sparse/mm/swapfile.c
+3f108af81Thhb242EmKjGCYkjx-GJA xenolinux-2.4.21-sparse/mm/vmalloc.c
index 3c1c21aa6c2e16f1126ab76b5a9fa069c4030e6f..a1c7c82f1538f18db2d34d2bdc2e02894375f26a 100644 (file)
@@ -53,12 +53,12 @@ public class CommandVbdCreate extends Command {
         String command = vd.dumpForXen(vbd);
 
         try {
-            FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd");
+            FileWriter fw = new FileWriter("/proc/xeno/vhd");
             fw.write(command);
             fw.flush();
             fw.close();
         } catch (IOException e) {
-            throw new CommandFailedException("Could not write VBD details to /proc/xeno/dom0/vhd", e);
+            throw new CommandFailedException("Could not write VBD details to /proc/xeno/vhd", e);
         }
 
         return "Created virtual block device "
index 2046525529322efe28646a6fc059fdf3443d7121..15b39eab05563094cdb4b00b88a858999841fb62 100644 (file)
@@ -53,13 +53,13 @@ public class CommandVbdCreatePhysical extends Command {
         String command = vd.dumpForXen(vbd);
 
         try {
-            FileWriter fw = new FileWriter("/proc/xeno/dom0/vhd");
+            FileWriter fw = new FileWriter("/proc/xeno/vhd");
             fw.write(command);
             fw.flush();
             fw.close();
         } catch (IOException e) {
             throw new CommandFailedException(
-                "Could not write VBD details to /proc/xeno/dom0/vhd",
+                "Could not write VBD details to /proc/xeno/vhd",
                 e);
         }
 
index e525ee485f6d8903111794a933aba6cf9690ddb9..16fd1953c6359ab129c415575375a6fa5734cb86 100644 (file)
@@ -16,7 +16,7 @@ public class CommandVbdList extends Command {
         String line;
 
         try {
-            in = new BufferedReader(new FileReader("/proc/xeno/dom0/vhd"));
+            in = new BufferedReader(new FileReader("/proc/xeno/vhd"));
             line = in.readLine();
             while (line != null) {
                 int domain = -1;
index c39dcf621b79a2d09a08471250d0c2cb54f2d401..e1b026b199a8cd2fea6bfd784271f8ee26e2faee 100644 (file)
@@ -1,55 +1,27 @@
-CC = gcc
-CFLAGS = -Wall -I../../xen/include -I../../xenolinux-2.4.21-sparse/include
-XI_CREATE = xi_create
-XI_START = xi_start
-XI_STOP = xi_stop
-XI_DESTROY = xi_destroy
-XI_BUILD = xi_build
-XI_PHYS_GRANT = xi_phys_grant
-XI_PHYS_REVOKE = xi_phys_revoke
-XI_PHYS_PROBE = xi_phys_probe
-
-all: $(XI_CREATE).o $(XI_START).o $(XI_STOP).o $(XI_DESTROY).o $(XI_BUILD).o \
-       $(XI_PHYS_GRANT).o $(XI_PHYS_REVOKE).o $(XI_PHYS_PROBE).o
-       $(CC) -o $(XI_CREATE) $(XI_CREATE).o
-       $(CC) -o $(XI_BUILD) $(XI_BUILD).o
-       $(CC) -o $(XI_START) $(XI_START).o
-       $(CC) -o $(XI_STOP) $(XI_STOP).o
-       $(CC) -o $(XI_DESTROY) $(XI_DESTROY).o
-       $(CC) -o $(XI_PHYS_GRANT) $(XI_PHYS_GRANT).o
-       $(CC) -o $(XI_PHYS_REVOKE) $(XI_PHYS_REVOKE).o
-       $(CC) -o $(XI_PHYS_PROBE) $(XI_PHYS_PROBE).o
-
-$(XI_CREATE).o: $(XI_CREATE).c dom0_defs.h dom0_ops.h mem_defs.h
-       $(CC) $(CFLAGS) -c $(XI_CREATE).c 
-
-internal_domain_build.o: internal_domain_build.c dom0_defs.h dom0_ops.h mem_defs.h
-       $(CC) $(CFLAGS) -c internal_domain_build.c 
-
-$(XI_START).o: $(XI_START).c dom0_defs.h dom0_ops.h mem_defs.h
-       $(CC) $(CFLAGS) -c $(XI_START).c 
-
-$(XI_STOP).o: $(XI_STOP).c dom0_defs.h dom0_ops.h mem_defs.h
-       $(CC) $(CFLAGS) -c $(XI_STOP).c 
-
-$(XI_DESTROY).o: $(XI_DESTROY).c dom0_ops.h dom0_defs.h
-       $(CC) $(CFLAGS) -c $(XI_DESTROY).c 
-
-$(XI_PHYS_GRANT).o: $(XI_PHYS_GRANT).c 
-       $(CC) $(CFLAGS) -c $(XI_PHYS_GRANT).c 
-
-$(XI_PHYS_REVOKE).o: $(XI_PHYS_REVOKE).c
-       $(CC) $(CFLAGS) -c $(XI_PHYS_REVOKE).c 
-
-$(XI_PHYS_PROBE).o: $(XI_PHYS_PROBE).c
-       $(CC) $(CFLAGS) -c $(XI_PHYS_PROBE).c 
+
+CC       = gcc
+CFLAGS   = -Wall -O3 
+CFLAGS  += -I../../xen/include -I../../xenolinux-2.4.21-sparse/include
+
+HDRS     = $(wildcard *.h)
+SRCS     = $(wildcard *.c)
+OBJS     = $(patsubst %.c,%.o,$(SRCS))
+
+TARGETS  = xi_create xi_start xi_stop xi_destroy xi_build 
+TARGETS += xi_phys_grant xi_phys_revoke xi_phys_probe xi_list 
+TARGETS += xi_sched_global xi_sched_domain xi_usage
+INSTALL  = $(TARGETS) xi_vifinit xi_helper
+
+all: $(TARGETS)
 
 install: all
-       cp -a xi_list xi_vifinit xi_helper $(XI_CREATE) $(XI_BUILD) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_PHYSDEV_GRANT) $(XI_PHYS_REVOKE) $(XI_PHYS_PROBE).o../../../install/bin
-       chmod 755 ../../../install/bin/xi_list
+       cp -a $(INSTALL) ../../../install/bin
        chmod 755 ../../../install/bin/xi_vifinit
        chmod 755 ../../../install/bin/xi_helper
 
+clean:
+       $(RM) *.o *.rpm $(TARGETS)
+
 rpm: all
        rm -rf staging
        mkdir staging
@@ -58,6 +30,6 @@ rpm: all
        mv staging/i386/*.rpm .
        rm -rf staging
 
-clean:
-       $(RM) *.o *.rpm $(XI_CREATE) $(XI_START) $(XI_STOP) $(XI_DESTROY) $(XI_BUILD) $(XI_PHYS_GRANT) $(XI_PHYS_REVOKE) $(XI_PHYS_PROBE)
+%: %.c $(HDRS) Makefile
+       $(CC) $(CFLAGS) -o $@ $<
 
index e79d85d41771f6c7f0dff053360fc252276f0eae..9ef8d0645d136c604a7c554650a98e82cc8f8357 100644 (file)
@@ -1,9 +1,121 @@
-#define PROC_XENO_ROOT  "xeno"
-#define PROC_CMD        "dom0_cmd"
-#define PROC_DOM_PREFIX "dom"
-#define PROC_DOM_MEM    "mem"
-#define PROC_DOM_DATA   "new_dom_data"
-#define PROC_DOMAINS    "domains"
 
-#define MAX_PATH        256
+#ifndef __DOM0_DEFS_H__
+#define __DOM0_DEFS_H__
 
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <string.h>
+
+#include <asm/types.h>
+
+#include "mem_defs.h"
+#include <asm-xeno/proc_cmd.h>
+#include <hypervisor-ifs/hypervisor-if.h>
+#include <hypervisor-ifs/dom0_ops.h>
+
+#define ERROR(_m)  \
+    fprintf(stderr, "ERROR: %s\n", (_m))
+
+#define PERROR(_m) \
+    fprintf(stderr, "ERROR: %s (%d = %s)\n", (_m), errno, strerror(errno))
+
+static inline int do_privcmd(unsigned int cmd, unsigned long data)
+{
+    int fd;
+
+    if ( (fd = open("/proc/xeno/privcmd", O_RDWR)) < 0 )
+    {
+        PERROR("Could not open proc interface");
+        return -1;
+    }
+
+    if ( ioctl(fd, cmd, data) < 0 )
+    {
+#ifndef SILENT_ERRORS_FROM_XEN
+        PERROR("Error when executing privileged control ioctl");
+#endif
+        close(fd);
+        return -1;
+    }
+
+    close(fd);
+    return 0;
+}
+
+static inline int xldev_to_physdev(int xldev)
+{
+    return do_privcmd(IOCTL_PRIVCMD_LINDEV_TO_XENDEV, 
+                      (unsigned long)xldev);
+}
+
+static inline int physdev_to_xldev(int physdev)
+{
+    return do_privcmd(IOCTL_PRIVCMD_XENDEV_TO_LINDEV, 
+                      (unsigned long)physdev);
+}
+
+static inline int do_xen_blkmsg(privcmd_blkmsg_t *blkmsg)
+{
+    return do_privcmd(IOCTL_PRIVCMD_BLKMSG, (unsigned long)blkmsg);
+}
+
+static inline int do_xen_hypercall(privcmd_hypercall_t *hypercall)
+{
+    return do_privcmd(IOCTL_PRIVCMD_HYPERCALL, (unsigned long)hypercall);
+}
+
+static inline int do_dom0_op(dom0_op_t *op)
+{
+    int ret = -1;
+    privcmd_hypercall_t hypercall;
+
+    hypercall.op     = __HYPERVISOR_dom0_op;
+    hypercall.arg[0] = (unsigned long)op;
+
+    if ( mlock(op, sizeof(*op)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( do_xen_hypercall(&hypercall) < 0 )
+        goto out2;
+
+    ret = 0;
+
+ out2: (void)munlock(op, sizeof(*op));
+ out1: return ret;
+}
+
+static inline int do_network_op(network_op_t *op)
+{
+    int ret = -1;
+    privcmd_hypercall_t hypercall;
+
+    hypercall.op     = __HYPERVISOR_network_op;
+    hypercall.arg[0] = (unsigned long)op;
+
+    if ( mlock(op, sizeof(*op)) != 0 )
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        goto out1;
+    }
+
+    if ( do_xen_hypercall(&hypercall) < 0 )
+        goto out2;
+
+    ret = 0;
+
+ out2: (void)munlock(op, sizeof(*op));
+ out1: return ret;
+}
+
+#endif /* __DOM0_DEFS_H__ */
diff --git a/tools/internal/dom0_ops.h b/tools/internal/dom0_ops.h
deleted file mode 100644 (file)
index 0764f83..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-
-#define NO_DOM0_OP_T
-#include "../../xen/include/hypervisor-ifs/dom0_ops.h"
-#undef  NO_DOM0_OP_T
-#include "../../xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h"
index 4ba84ffaeefee36f0057743a2d77cec026ded85c..4361d6766cb673a2470eb8fcd100115f8b8a7f23 100644 (file)
@@ -1,24 +1,16 @@
-/*
- * memory related definitions needed for userspace domain builder dom0 application. these _need_ to
- * be kept in sync with the kernel .h files they were copied over from or something horrible will
- * happen. remmember: god kills a kitten every time you forget to keep these in sync.
- * 
- * KAF: Boris, these constants are all fixed by x86 hardware. So the kittens are safe for now :-)
- * 
- * Copyright 2002 by B Dragovic
- */
 
-/* copied over from hypervisor: include/asm-i386/page.h */
+#ifndef __MEM_DEFS_H__
+#define __MEM_DEFS_H__
 
 #define _PAGE_PRESENT   0x001
-#define _PAGE_RW    0x002
-#define _PAGE_USER  0x004
-#define _PAGE_PWT   0x008
-#define _PAGE_PCD   0x010
+#define _PAGE_RW        0x002
+#define _PAGE_USER      0x004
+#define _PAGE_PWT       0x008
+#define _PAGE_PCD       0x010
 #define _PAGE_ACCESSED  0x020
-#define _PAGE_DIRTY 0x040
+#define _PAGE_DIRTY     0x040
 #define _PAGE_PAT       0x080
-#define _PAGE_PSE   0x080
+#define _PAGE_PSE       0x080
 #define _PAGE_GLOBAL    0x100
 
 
@@ -40,6 +32,4 @@ typedef struct { unsigned long l2_lo; } l2_pgentry_t;
 #define l2_table_offset(_a) \
           ((_a) >> L2_PAGETABLE_SHIFT)
 
-/* local definitions */
-
-#define nr_2_page(x) ((x) << PAGE_SHIFT)
+#endif /* __MEM_DEFS_H__ */
index 805ab22a2a7d9667c3b79e4ece704d708e85293b..991666436f6e0e237afd95a5c5f632ae7d213a27 100644 (file)
-/* 
- * XenoDomainBuilder, copyright (c) Boris Dragovic, bd240@cl.cam.ac.uk
- * This code is released under terms and conditions of GNU GPL :).
- * Usage: <executable> <mem_kb> <os image> <num_vifs> 
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "asm-xeno/dom0.h"
-#include "hypervisor-ifs/hypervisor-if.h"
-#include "dom0_ops.h"
+
+#include "hypervisor-ifs/dom0_ops.h"
 #include "dom0_defs.h"
 #include "mem_defs.h"
 
-#define PERR_STRING "Xeno Domain Builder"
-
 #define GUEST_SIG   "XenoGues"
 #define SIG_LEN    8
 
-/* Watch for precedence when using thses ones... */
-#define PROC_XENO_DOM0_CMD "/proc/" PROC_XENO_ROOT "/" PROC_CMD
-#define PROC_XENO_DOMAINS "/proc" PROC_XENO_ROOT "/" PROC_DOMAINS
-
-/*
- * NB. No ring-3 access in initial guestOS pagetables. Note that we allow
- * ring-3 privileges in the page directories, so that the guestOS may later
- * decide to share a 4MB region with applications.
- */
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
 #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
 
-/* standardized error reporting function */
-static void dberr(char *msg)
+static long get_tot_pages(int domain_id)
 {
-    printf("%s: %s\n", PERR_STRING, msg);
+    dom0_op_t op;
+    op.cmd = DOM0_GETDOMAININFO;
+    op.u.getdominfo.domain = domain_id;
+    return (do_dom0_op(&op) < 0) ? -1 : op.u.getdominfo.tot_pages;
 }
 
-/* status reporting function */
-static void dbstatus(char * msg)
+static int get_pfn_list(
+    int domain_id, unsigned long *pfn_buf, unsigned long max_pfns)
 {
-    printf("Domain Builder: %s\n", msg);
-}
-
+    dom0_op_t op;
+    int ret;
+    op.cmd = DOM0_GETMEMLIST;
+    op.u.getmemlist.domain   = domain_id;
+    op.u.getmemlist.max_pfns = max_pfns;
+    op.u.getmemlist.buffer   = pfn_buf;
+
+    if ( mlock(pfn_buf, max_pfns * sizeof(unsigned long)) != 0 )
+    {
+        PERROR("Could not lock pfn list buffer");
+        return -1;
+    }    
 
-/* clean up domain's memory allocations */
-static void dom_mem_cleanup(dom_mem_t * dom_mem)
-{
-    int fd;
-    struct dom0_unmapdommem_args argbuf;
-           
-    fd = open("/proc/xeno/dom0_cmd", O_WRONLY);
-    if(fd < 0){
-        perror("openning /proc/xeno/dom0_cmd");
-       return;
-    }
-    
-    argbuf.vaddr = dom_mem->vaddr;
-    argbuf.start_pfn = dom_mem->start_pfn;
-    argbuf.tot_pages = dom_mem->tot_pages;
+    ret = do_dom0_op(&op);
 
-    if (ioctl(fd, IOCTL_DOM0_UNMAPDOMMEM, &argbuf) < 0) {
-        dbstatus("Error unmapping domain's memory.\n");
-    }
+    (void)munlock(pfn_buf, max_pfns * sizeof(unsigned long));
 
-    close(fd);
+    return (ret < 0) ? -1 : op.u.getmemlist.num_pfns;
 }
 
-static int map_dom_mem(unsigned long pfn, int pages, int dom, 
-                       dom_mem_t * dom_mem)
+static int send_pgupdates(page_update_request_t *updates, int nr_updates)
 {
-    struct dom0_mapdommem_args argbuf;
-    int fd;
-
-    argbuf.domain = dom;
-    argbuf.start_pfn = pfn;
-    argbuf.tot_pages = pages;
-  
-    fd = open("/proc/xeno/dom0_cmd", O_RDWR);
-    if (fd < 0) {
-        perror("openning /proc/xeno/dom0_cmd");
-        return -1;
-    }
-  
-    dom_mem->domain = dom;
-    dom_mem->start_pfn = pfn;
-    dom_mem->tot_pages = pages;
-    dom_mem->vaddr = ioctl(fd, IOCTL_DOM0_MAPDOMMEM, &argbuf);
-    
-    if (dom_mem->vaddr == -1) {
-        perror("mapping domain memory");
-       close(fd);
-       return -1;
+    int ret = -1;
+    privcmd_hypercall_t hypercall;
+
+    hypercall.op     = __HYPERVISOR_pt_update;
+    hypercall.arg[0] = (unsigned long)updates;
+    hypercall.arg[1] = (unsigned long)nr_updates;
+
+    if ( mlock(updates, nr_updates * sizeof(*updates)) != 0 )
+    {
+        PERROR("Could not lock pagetable update array");
+        goto out1;
     }
-    close(fd);
 
-    return 0;
+    if ( do_xen_hypercall(&hypercall) < 0 )
+        goto out2;
+
+    ret = 0;
+
+ out2: (void)munlock(updates, nr_updates * sizeof(*updates));
+ out1: return ret;
 }
 
-/* read the kernel header, extracting the image size and load address. */
+/* Read the kernel header, extracting the image size and load address. */
 static int read_kernel_header(int fd, long dom_size, 
                              unsigned long * load_addr, size_t * ksize)
 {
     char signature[8];
-    char status[MAX_PATH];
+    char status[1024];
     struct stat stat;
     
-    if(fstat(fd, &stat) < 0){
-        perror(PERR_STRING);
+    if ( fstat(fd, &stat) < 0 )
+    {
+        PERROR("Cannot stat the kernel image");
        return -1;
     }
 
-    if(stat.st_size > (dom_size << 10)){
+    if ( (stat.st_size * 2) > (dom_size << 10) )
+    {
         sprintf(status, "Kernel image size %ld larger than requested "
                 "domain size %ld\n Terminated.\n", stat.st_size, dom_size);
-        dberr(status);
+        ERROR(status);
        return -1;
     }
     
     read(fd, signature, SIG_LEN);
-    if(strncmp(signature, GUEST_SIG, SIG_LEN)){
-        dberr("Kernel image does not contain required signature. "
+    if ( strncmp(signature, GUEST_SIG, SIG_LEN) )
+    {
+        ERROR("Kernel image does not contain required signature. "
               "Terminating.\n");
        return -1;
     }
@@ -137,62 +101,165 @@ static int read_kernel_header(int fd, long dom_size,
     return 0;
 }
 
-/* this is the main guestos setup function,
- * returnes domain descriptor structure to be used when launching
- * the domain by hypervisor to do some last minute initialization.
- * page table initialization is done by making a list of page table
- * requests that are handeled by the hypervisor in the ordinary
- * manner. this way, many potentially messy things are avoided...
- */ 
-#define PAGE_TO_VADDR(_pfn) ((void *)(dom_mem->vaddr + ((_pfn) * PAGE_SIZE)))
-static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
-                                    unsigned long virt_load_addr, size_t ksize, dom_mem_t *dom_mem)
+static int devmem_fd;
+
+static int init_pfn_mapper(void)
+{
+    if ( (devmem_fd = open("/dev/mem", O_RDWR)) < 0 )
+    {
+        PERROR("Could not open /dev/mem");
+        return -1;
+    }
+    return 0;
+}
+
+static void *map_pfn(unsigned long pfn)
+{
+    void *vaddr = mmap(NULL, PAGE_SIZE, PROT_READ|PROT_WRITE,
+                       MAP_SHARED, devmem_fd, pfn << PAGE_SHIFT);
+    if ( vaddr == MAP_FAILED )
+    {
+        PERROR("Could not mmap a domain pfn using /dev/mem");
+        return NULL;
+    }
+    return vaddr;
+}
+
+static void unmap_pfn(void *vaddr)
+{
+    (void)munmap(vaddr, PAGE_SIZE);
+}
+
+static int clear_domain_page(unsigned long pfn)
+{
+    void *vaddr = map_pfn(pfn);
+    if ( vaddr == NULL )
+        return -1;
+    memset(vaddr, 0, PAGE_SIZE);
+    unmap_pfn(vaddr);
+    return 0;
+}
+
+static int copy_to_domain_page(unsigned long dst_pfn, void *src_page)
+{
+    void *vaddr = map_pfn(dst_pfn);
+    if ( vaddr == NULL )
+        return -1;
+    memcpy(vaddr, src_page, PAGE_SIZE);
+    unmap_pfn(vaddr);
+    return 0;
+}
+
+static int setup_guestos(
+    int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages,
+    unsigned long virt_load_addr, size_t ksize, dom_meminfo_t *meminfo)
 {
-    dom_meminfo_t *meminfo = NULL;
     unsigned long *page_array = NULL;
-    page_update_request_t *pgt_updates = NULL;
+    page_update_request_t *pgt_update_arr = NULL, *pgt_updates = NULL;
     int alloc_index, num_pt_pages;
     unsigned long l2tab;
     unsigned long l1tab = 0;
     unsigned long num_pgt_updates = 0;
-    unsigned long count, pt_start;
-    struct dom0_dopgupdates_args pgupdate_req;
-    int cmd_fd;
-    int result;
-
-    meminfo     = (dom_meminfo_t *)malloc(sizeof(dom_meminfo_t));
-    page_array  = malloc(dom_mem->tot_pages * 4);
-    if (!meminfo || !page_array) {
-       dberr ("Could not allocate memory");
+    unsigned long count, pt_start, i, j;
+
+    memset(meminfo, 0, sizeof(*meminfo));
+
+    if ( init_pfn_mapper() < 0 )
+        goto error_out;
+
+    pgt_updates = malloc((tot_pages + 1024) * 3
+                         * sizeof(page_update_request_t));
+    page_array = malloc(tot_pages * sizeof(unsigned long));
+    pgt_update_arr = pgt_updates;
+    if ( (pgt_update_arr == NULL) || (page_array == NULL) )
+    {
+       PERROR("Could not allocate memory");
        goto error_out;
     }
-    pgt_updates = (page_update_request_t *)dom_mem->vaddr;
-    alloc_index = dom_mem->tot_pages - 1;
 
-    memset(meminfo, 0, sizeof(*meminfo));
+    if ( get_pfn_list(dom, page_array, tot_pages) != tot_pages )
+    {
+       PERROR("Could not get the page frame list");
+       goto error_out;
+    }
+
+    /* Load the guest OS image. */
+    for ( i = 0; i < ksize; i += PAGE_SIZE )
+    {
+        char page[PAGE_SIZE];
+        int size = ((ksize-i) < PAGE_SIZE) ? (ksize-i) : PAGE_SIZE;
+        if ( read(kernel_fd, page, size) != size )
+        {
+            PERROR("Error reading kernel image, could not"
+                   " read the whole image.");
+            goto error_out;
+        } 
+        copy_to_domain_page(page_array[i>>PAGE_SHIFT], page);
+    }
+
+    /* Load the initial ramdisk image. */
+    if ( initrd_fd >= 0 )
+    {
+       struct stat stat;
+       unsigned long isize;
+
+       if ( fstat(initrd_fd, &stat) < 0 )
+        {
+            PERROR("Could not stat the initrd image");
+            goto error_out;
+       }
+       isize = stat.st_size;
+        if ( ((isize + ksize) * 2) > (tot_pages << PAGE_SHIFT) )
+        {
+            ERROR("Kernel + initrd too big to safely fit in domain memory");
+            goto error_out;
+        }
 
-    memcpy(page_array, (void *)dom_mem->vaddr, dom_mem->tot_pages * 4);
+        meminfo->virt_mod_addr = virt_load_addr + i;
+        meminfo->virt_mod_len  = isize;
 
-    /* Count bottom-level PTs, rounding up. Include one PTE for shared info. */
+        for ( j = 0; j < isize; j += PAGE_SIZE, i += PAGE_SIZE )
+        {
+            char page[PAGE_SIZE];
+            int size = ((isize-j) < PAGE_SIZE) ? (isize-j) : PAGE_SIZE;
+            if ( read(initrd_fd, page, size) != size )
+            {
+                PERROR("Error reading initrd image, could not"
+                       " read the whole image.");
+                goto error_out;
+            } 
+            copy_to_domain_page(page_array[i>>PAGE_SHIFT], page);
+        }
+    }
+
+    alloc_index = tot_pages - 1;
+
+    /*
+     * Count bottom-level PTs, rounding up. Include one PTE for shared info. We
+     * therefore add 1024 because 1 is for shared_info, 1023 is to round up.
+     */
     num_pt_pages = 
-        (l1_table_offset(virt_load_addr) + dom_mem->tot_pages + 1024) / 1024;
+        (l1_table_offset(virt_load_addr) + tot_pages + 1024) / 1024;
 
     /* We must also count the page directory. */
     num_pt_pages++;
 
     /* Index of first PT page. */
-    pt_start = dom_mem->tot_pages - num_pt_pages;
+    pt_start = tot_pages - num_pt_pages;
 
-    /* first allocate page for page dir. allocation goes backwards from the
-     * end of the allocated physical address space.
+    /*
+     * First allocate page for page dir. Allocation goes backwards from the end
+     * of the allocated physical address space.
      */
-    l2tab = *(page_array + alloc_index) << PAGE_SHIFT; 
-    memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
+    l2tab = page_array[alloc_index] << PAGE_SHIFT;
+    if ( clear_domain_page(page_array[alloc_index]) < 0 )
+        goto error_out;
     alloc_index--;
     meminfo->l2_pgt_addr = l2tab;
-    meminfo->virt_shinfo_addr = virt_load_addr + nr_2_page(dom_mem->tot_pages);
+    meminfo->virt_shinfo_addr = virt_load_addr + (tot_pages << PAGE_SHIFT);
 
-    /* pin down l2tab addr as page dir page - causes hypervisor to provide
+    /*
+     * Pin down l2tab addr as page dir page - causes hypervisor to provide
      * correct protection for the page
      */ 
     pgt_updates->ptr = l2tab | PGREQ_EXTENDED_COMMAND;
@@ -206,15 +273,16 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
      * Xen during final setup.
      */
     l2tab += l2_table_offset(virt_load_addr) * sizeof(l2_pgentry_t);
-    for ( count = 0; count < (dom_mem->tot_pages + 1); count++ )
+    for ( count = 0; count < (tot_pages + 1); count++ )
     {    
         if ( !((unsigned long)l1tab & (PAGE_SIZE-1)) ) 
         {
-            l1tab = *(page_array + alloc_index) << PAGE_SHIFT;
-            memset(PAGE_TO_VADDR(alloc_index), 0, PAGE_SIZE);
+            l1tab = page_array[alloc_index] << PAGE_SHIFT;
+            if ( clear_domain_page(page_array[alloc_index]) < 0 )
+                goto error_out;
             alloc_index--;
                        
-            l1tab += l1_table_offset(virt_load_addr + nr_2_page(count)) 
+            l1tab += l1_table_offset(virt_load_addr + (count << PAGE_SHIFT)) 
                 * sizeof(l1_pgentry_t);
 
             /* make apropriate entry in the page directory */
@@ -226,12 +294,14 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
         }
 
         /* The last PTE we consider is filled in later by Xen. */
-        if ( count == dom_mem->tot_pages ) break;
+        if ( count == tot_pages ) break;
                
+        printf("%lu: %08lx\n", count, page_array[count]);
+
         if ( count < pt_start )
         {
             pgt_updates->ptr = l1tab;
-            pgt_updates->val = (*(page_array + count) << PAGE_SHIFT) | L1_PROT;
+            pgt_updates->val = (page_array[count] << PAGE_SHIFT) | L1_PROT;
             pgt_updates++;
             num_pgt_updates++;
             l1tab += sizeof(l1_pgentry_t);
@@ -240,195 +310,82 @@ static dom_meminfo_t *setup_guestos(int dom, int kernel_fd, int initrd_fd,
         {
             pgt_updates->ptr = l1tab;
             pgt_updates->val = 
-               ((*(page_array + count) << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
+               ((page_array[count] << PAGE_SHIFT) | L1_PROT) & ~_PAGE_RW;
             pgt_updates++;
             num_pgt_updates++;
             l1tab += sizeof(l1_pgentry_t);
         }
 
         pgt_updates->ptr = 
-           (*(page_array + count) << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
+           (page_array[count] << PAGE_SHIFT) | PGREQ_MPT_UPDATE;
         pgt_updates->val = count;
         pgt_updates++;
         num_pgt_updates++;
     }
 
-    meminfo->virt_startinfo_addr = virt_load_addr + nr_2_page(alloc_index - 1);
-    meminfo->domain = dom;
-
-    free(page_array);
-
-    /*
-     * Send the page update requests down to the hypervisor.
-     * NB. We must do this before loading the guest OS image!
-     */
-    if ( (cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY)) < 0 )
-    {
-       dberr ("Could not open " PROC_XENO_DOM0_CMD);
-       goto error_out;
-    }
-
-    pgupdate_req.pgt_update_arr  = (unsigned long)dom_mem->vaddr;
-    pgupdate_req.num_pgt_updates = num_pgt_updates;
-    result = ioctl(cmd_fd, IOCTL_DOM0_DOPGUPDATES, &pgupdate_req);
-    close(cmd_fd);
-    if (result < 0) {
-       dberr ("Could not build domain page tables.");
-       goto error_out;
-    }
-
-    /* Load the guest OS image. */
-    if( read(kernel_fd, (char *)dom_mem->vaddr, ksize) != ksize )
-    {
-        dberr("Error reading kernel image, could not"
-              " read the whole image.");
-       goto error_out;
-    }
-
-    if( initrd_fd >= 0)
-    {
-       struct stat stat;
-       unsigned long isize;
-
-       if(fstat(initrd_fd, &stat) < 0){
-            perror(PERR_STRING);
-            goto error_out;
-       }
-       isize = stat.st_size;
-
-       if( read(initrd_fd, ((char *)dom_mem->vaddr)+ksize, isize) != isize )
-        {
-           dberr("Error reading initrd image, could not"
-                 " read the whole image. Terminating.");
-           goto error_out;
-        }
-
-       meminfo->virt_mod_addr = virt_load_addr + ksize;
-       meminfo->virt_mod_len  = isize;
+    printf("XHDHFDHGFGHFGXXX\n");
+    sleep(4);
 
-    }
+    meminfo->virt_startinfo_addr =
+        virt_load_addr + ((alloc_index-1)<<PAGE_SHIFT);
 
+    /* Send the page update requests down to the hypervisor. */
+    if ( send_pgupdates(pgt_update_arr, num_pgt_updates) < 0 )
+        goto error_out;
 
-    return meminfo;
+    free(page_array);
+    free(pgt_update_arr);
+    return 0;
 
  error_out:
-    if (meminfo)
-       free(meminfo);
-    if (page_array)
+    if ( page_array == NULL )
        free(page_array);
-
-    return NULL;
+    if ( pgt_update_arr == NULL )
+       free(pgt_update_arr);
+    return -1;
 }
 
-static int launch_domain(dom_meminfo_t  * meminfo)
-{
-    dom0_op_t dop;
-    int cmd_fd;
-
-    cmd_fd = open(PROC_XENO_DOM0_CMD, O_WRONLY);
-    if(cmd_fd < 0){
-        perror(PERR_STRING);
-        return -1;
-    }
-
-    dop.cmd = DOM0_BUILDDOMAIN;
-    memcpy(&dop.u.meminfo, meminfo, sizeof(dom_meminfo_t));
-    write(cmd_fd, &dop, sizeof(dom0_op_t));
-    close(cmd_fd);
-
-    return 0;
-}
-
-static int get_domain_info (int domain_id,
-                            int *pg_head,
-                            int *tot_pages)
-{
-    FILE *f; 
-    char domains_line[256];
-    int read_id;
-
-    f = fopen (PROC_XENO_DOMAINS, "r");
-    if (f == NULL) return -1;
-
-    read_id = -1;
-    while (fgets (domains_line, 256, f) != 0)
-    { 
-        int trans;
-       read_id = -1;
-        trans = sscanf (domains_line, "%d %*d %*d %*d %*d %*d %x %d %*s", &read_id
-                        , pg_head, tot_pages);
-       if (trans != 3) {
-           dberr ("format of " PROC_XENO_DOMAINS " changed -- wrong kernel version?");
-           read_id = -1;
-           break;
-       }
-
-        if (read_id == domain_id) {
-           break;
-        }
-    }
-
-    fclose (f);
-
-    if (read_id == -1) {
-        errno = ESRCH;
-    }
-
-    return 0;
-}
-
-
 int main(int argc, char **argv)
 {
-
-    dom_mem_t dom_os_image;
-    dom_meminfo_t * meminfo;
+    dom0_op_t launch_op;
     size_t ksize;
     unsigned long load_addr;
+    long tot_pages;
     int kernel_fd, initrd_fd = -1;
     int count;
     int cmd_len;
     int args_start = 4;
     char initrd_name[1024];
     int domain_id;
-    int pg_head;
-    int tot_pages;
     int rc;
 
-    /**** this argument parsing code is really _gross_. rewrite me! ****/
-
-    if(argc < 4) {
-        dberr("Usage: dom_builder <domain_id> <image> <num_vifs> "
-             "[<initrd=initrd_name>] <boot_params>\n");
-        return -1;
+    if ( argc < 4 )
+    {
+        fprintf(stderr, "Usage: dom_builder <domain_id> <image> <num_vifs> "
+                "[<initrd=initrd_name>] <boot_params>\n");
+        return 1;
     }
 
-    /* Look up information about the domain */
     domain_id = atol(argv[1]);
-    if ( get_domain_info (domain_id, &pg_head, &tot_pages) != 0 ) 
+    if ( (tot_pages = get_tot_pages(domain_id)) < 0 )
     {
-        perror ("Could not find domain information");
-       return -1;
+        PERROR("Could not find total pages for domain");
+       return 1;
     }
-            
+
     kernel_fd = open(argv[2], O_RDONLY);
-    if (kernel_fd < 0) {
-        perror ("Could not open kernel image");
-       return -1;
+    if ( kernel_fd < 0 )
+    {
+        PERROR("Could not open kernel image");
+       return 1;
     }
 
     rc = read_kernel_header(kernel_fd,
                            tot_pages << (PAGE_SHIFT - 10), 
                            &load_addr, &ksize);
     if ( rc < 0 )
-       return -1;
+       return 1;
     
-
-    /* map domain's memory */
-    if ( map_dom_mem(pg_head, tot_pages,
-                     domain_id, &dom_os_image) )
-       return -1;
-
     if( (argc > args_start) && 
         (strncmp("initrd=", argv[args_start], 7) == 0) )
     {
@@ -438,41 +395,40 @@ int main(int argc, char **argv)
        args_start++;
         
        initrd_fd = open(initrd_name, O_RDONLY);
-       if(initrd_fd < 0){
-            perror(PERR_STRING);
-           return -1;
+       if ( initrd_fd < 0 )
+        {
+            PERROR("Could not open the initial ramdisk image");
+           return 1;
        }
     }
 
-    /* the following code does the actual domain building */
-    meminfo = setup_guestos(domain_id, kernel_fd, initrd_fd, load_addr, 
-                           ksize, &dom_os_image); 
-    if (!meminfo)
-       return -1;
+    if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages,
+                       load_addr, ksize, &launch_op.u.meminfo) < 0 )
+        return 1;
 
-    if (initrd_fd >= 0)
+    if ( initrd_fd >= 0 )
        close(initrd_fd);
     close(kernel_fd);
 
-    /* and unmap the new domain's memory image since we no longer need it */
-    dom_mem_cleanup(&dom_os_image);
-
-    meminfo->virt_load_addr = load_addr;
-    meminfo->num_vifs = atoi(argv[3]);
-    meminfo->cmd_line[0] = '\0';
+    launch_op.u.meminfo.domain         = domain_id;
+    launch_op.u.meminfo.virt_load_addr = load_addr;
+    launch_op.u.meminfo.num_vifs       = atoi(argv[3]);
+    launch_op.u.meminfo.cmd_line[0]    = '\0';
     cmd_len = 0;
-    for(count = args_start; count < argc; count++){
-        if(cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1){
-            dberr("Size of image boot params too big!\n");
+    for ( count = args_start; count < argc; count++ )
+    {
+        if ( cmd_len + strlen(argv[count]) > MAX_CMD_LEN - 1 ) 
+        {
+            ERROR("Size of image boot params too big!\n");
             break;
         }
-        strcat(meminfo->cmd_line, argv[count]);
-        strcat(meminfo->cmd_line, " ");
+        strcat(launch_op.u.meminfo.cmd_line, argv[count]);
+        strcat(launch_op.u.meminfo.cmd_line, " ");
         cmd_len += strlen(argv[count] + 1);
     }
 
-    /* and launch the domain */
-    rc = launch_domain(meminfo); 
+    launch_op.cmd = DOM0_BUILDDOMAIN;
+    rc = do_dom0_op(&launch_op);
     
-    return 0;
+    return (rc != 0) ? 1 : 0;
 }
index ad893285e26f68084176b163e7c70f84583cff86..d003979731385370d3debcf2d72eedbc34d5a1c8 100644 (file)
@@ -4,90 +4,44 @@
  * Usage: <executable> <mem_kb> <os image> <num_vifs> 
  */
 
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <string.h>
-
-#include "dom0_ops.h"
+#include <hypervisor-ifs/dom0_ops.h>
 #include "dom0_defs.h"
 #include "mem_defs.h"
-#include "asm-xeno/dom0.h"
-
-/***********************************************************************/
 
 static char *argv0 = "internal_domain_create";
 
-static void ERROR (char *message)
-{
-  fprintf (stderr, "%s: %s\n", argv0, message);
-  exit (-1);
-}
-
-static void PERROR (char *message)
-{
-  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
-  exit (-1);
-}
-
-/***********************************************************************/
-
 static int create_new_domain(long req_mem, char *name)
 {
-    char cmd_path[MAX_PATH];
-    int cmd_fd;
-    int dom_id;
-    struct dom0_createdomain_args argbuf;
+    int err;
+    dom0_op_t op;
 
-    /* open the /proc command interface */
-    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
-    cmd_fd = open(cmd_path, O_RDWR);
-    if(cmd_fd < 0){
-        PERROR ("Could not open PROC_CMD interface");
-        return -1;
-    }
+    op.cmd = DOM0_CREATEDOMAIN;
+    op.u.newdomain.memory_kb = req_mem;
+    strncpy(op.u.newdomain.name, name, MAX_DOMAIN_NAME);
+    op.u.newdomain.name[MAX_DOMAIN_NAME-1] = '\0';
 
-    argbuf.kb_mem = req_mem;
-    argbuf.name = name;
-    dom_id = ioctl(cmd_fd, IOCTL_DOM0_CREATEDOMAIN, &argbuf);
-    if (dom_id < 0) {
-      PERROR("creating new domain");
-    }
-    close(cmd_fd);
-    return dom_id;
-}    
+    err = do_dom0_op(&op);
 
-/***********************************************************************/
+    return (err < 0) ? err : op.u.newdomain.domain;
+}    
 
 int main(int argc, char **argv)
 {
-  int dom_id;
-
-  if (argv[0] != NULL) 
-    {
-      argv0 = argv[0];
-    }
-
-  if(argc != 3) 
-    {
-      fprintf (stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0);
-      return -1;
-    }
-
-  dom_id = create_new_domain(atol(argv[1]), argv[2]);
-
-  if(dom_id < 0)
+    int dom_id;
+    
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
+    
+    if ( argc != 3 ) 
     {
-      return -1;
+        fprintf(stderr, "Usage: %s <kbytes-mem> <domain-name>\n", argv0);
+        return 1;
     }
-
-  fprintf (stdout, "%d\n", dom_id);
-  return 0;
+    
+    dom_id = create_new_domain(atol(argv[1]), argv[2]);
+    if ( dom_id < 0 )
+        return 1;
+    
+    printf("%d\n", dom_id);
+    return 0;
 }
index bffe1d350da24e432f7704a8bc107331280b0de0..d6b7a09763f8c3109342c94caa60ab9aa0f185bd 100644 (file)
@@ -1,81 +1,43 @@
-/* 
- * A very(!) simple program to kill a domain. (c) Boris Dragovic
- * Usage: <executable> <mem_kb> <os image> <num_vifs> 
- */
 
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "dom0_ops.h"
+#include "hypervisor-ifs/dom0_ops.h"
 #include "dom0_defs.h"
-
-/***********************************************************************/
+#include "mem_defs.h"
 
 static char *argv0 = "internal_domain_stop";
 
-static void ERROR (char *message)
-{
-  fprintf (stderr, "%s: %s\n", argv0, message);
-  exit (-1);
-}
-
-static void PERROR (char *message)
-{
-  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
-  exit (-1);
-}
-
-/***********************************************************************/
-
-static int do_kill_domain(int dom_id, int force)
+static int kill_domain(int dom_id, int force)
 {
-    char cmd_path[MAX_PATH];
-    dom0_op_t dop;
-    int cmd_fd;
+    int err;
+    dom0_op_t op;
 
-    dop.cmd = DOM0_DESTROYDOMAIN;
-    dop.u.killdomain.domain = dom_id;
-    dop.u.killdomain.force  = force;
+    op.cmd = DOM0_DESTROYDOMAIN;
+    op.u.killdomain.domain = dom_id;
+    op.u.killdomain.force  = force;
 
-    /* open the /proc command interface */
-    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
-    cmd_fd = open(cmd_path, O_WRONLY);
-    if(cmd_fd < 0){
-        PERROR ("Count not open PROC_CMD interface");
-    }
-
-    write(cmd_fd, &dop, sizeof(dom0_op_t));
-    close(cmd_fd);
+    err = do_dom0_op(&op);
 
-    return 0;
+    return (err < 0) ? -1 : 0;
 }
 
 int main(int argc, char **argv)
 {
-  int ret;
-
-  if (argv[0] != NULL) 
-    {
-      argv0 = argv[0];
-    }
-
-  if ( (argc < 2) || (argc > 3) )
+    int ret;
+    
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
+    
+    if ( (argc < 2) || (argc > 3) )
     {
     usage:
         fprintf(stderr, "Usage: %s [-f] <domain_id>\n", argv0);
-        fprintf(stderr, " -f: Forces immediate destruction of specified domain\n");
-        ret = -1;
-        goto out;
+        fprintf(stderr, " -f: Forces immediate destruction of <domain_id>\n");
+        return 1;
     }
-
-    if ( (argc == 3) && strcmp("-f", argv[1]) ) goto usage;
-
-    ret = do_kill_domain(atoi(argv[argc-1]), argc == 3);
-
-out:
-    return ret;
+    
+    if ( (argc == 3) && strcmp("-f", argv[1]) )
+        goto usage;
+    
+    ret = kill_domain(atoi(argv[argc-1]), argc == 3);
+    
+    return (ret != 0) ? 1 : 0;
 }
diff --git a/tools/internal/xi_list b/tools/internal/xi_list
deleted file mode 100755 (executable)
index e909018..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-#
-# xi_list
-#
-# This is a silly little script to dump the currently running domains.
-# The output format is a series of space-separate fields for each domain:
-#
-#  1. Domain id
-#  2. Processor
-#  3. Has CPU (1 => true, 0 => false)
-#  4. State (integer)
-#  5. State (RUNNING, INTERRUPTABLE, UNINTERRUPTABLE, WAIT, SUSPENDED, DYING)
-#  6. MCU advance
-#  7. Total pages
-#  8. Name
-
-INPUT_FILE=/proc/xeno/domains
-
-awk -f - $INPUT_FILE <<EOF
-{
-  dom_id = \$1;
-
-  processor = \$2;
-
-  has_cpu = \$3;
-
-  state = "UNKNOWN";
-
-  if (\$4 == 0)  state = "RUNNING";
-  if (\$4 == 1)  state = "INTERRUPTIBLE";
-  if (\$4 == 2)  state = "UNINTERRUPTABLE";
-  if (\$4 == 4)  state = "WAIT";
-  if (\$4 == 8)  state = "SUSPENDED";
-  if (\$4 == 16) state = "DYING";
-
-  mcu_advance = \$6;
-
-  tot_pages = \$8;
-
-  printf "%d %d %d %d %s %d %d %s", dom_id, processor, has_cpu, \$4, state, mcu_advance, tot_pages, \$9;
-  for (i = 10; i < NF; i ++) {
-    printf " %s", \$i;
-  }
-  printf "\n";
-}
-EOF 
diff --git a/tools/internal/xi_list.c b/tools/internal/xi_list.c
new file mode 100644 (file)
index 0000000..ad6b5d3
--- /dev/null
@@ -0,0 +1,76 @@
+/******************************************************************************
+ * xi_list.c
+ * 
+ * This is a silly little program to dump the currently running domains.
+ * The output format is a series of space-separate fields for each domain:
+ * 
+ *  1. Domain id
+ *  2. Processor
+ *  3. Has CPU (1 => true, 0 => false)
+ *  4. State (integer)
+ *  5. State (RUNNING, INTERRUPTIBLE, UNINTERRUPTIBLE, WAIT, SUSPENDED, DYING)
+ *  6. Pending events (hex value)
+ *  7. MCU advance
+ *  8. Total pages
+ *  9. Name
+ */
+
+/*
+ * Xen indicates when we've read info on all domains by returning error ESRCH. 
+ * We don't want the helper functiosn to interpret this as a real error!
+ */
+#define SILENT_ERRORS_FROM_XEN
+
+#include "hypervisor-ifs/dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+static char *argv0 = "internal_domain_list";
+
+static char *statestr(int state)
+{
+    switch ( state )
+    {
+    case  0: return "RUNNING";
+    case  1: return "INTERRUPTIBLE";
+    case  2: return "UNINTERRUPTIBLE";
+    case  4: return "WAIT";
+    case  8: return "SUSPENDED";
+    case 16: return "DYING";
+    default: return "UNKNOWN";
+    }
+    return NULL;
+}
+
+int main(int argc, char **argv)
+{
+    dom0_op_t op;
+
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
+
+    if ( argc != 1 ) 
+    {
+        fprintf(stderr, "Usage: %s\n", argv0);
+        return 1;
+    }
+
+    op.cmd = DOM0_GETDOMAININFO;
+    op.u.getdominfo.domain = 0;
+    while ( do_dom0_op(&op) >= 0 )
+    {
+        printf("%8d %2d %1d %2d %s %08x %8ld %8d %s\n",
+               op.u.getdominfo.domain, 
+               op.u.getdominfo.processor,
+               op.u.getdominfo.has_cpu,
+               op.u.getdominfo.state,
+               statestr(op.u.getdominfo.state),
+               op.u.getdominfo.hyp_events,
+               op.u.getdominfo.mcu_advance,
+               op.u.getdominfo.tot_pages,
+               op.u.getdominfo.name);
+        op.u.getdominfo.domain++;
+    }
+
+    return 0;
+}
index 368414f4f51465a023c9bf82af09f3aa97f2c034..05630e242903b136b5bfd44645d9f9d9acf12a71 100644 (file)
@@ -1,50 +1,43 @@
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <sys/fcntl.h>
-#include <string.h>
-#include <stdlib.h>
 
-#include "hypervisor-ifs/block.h"
+#define _GNU_SOURCE
+#include "dom0_defs.h"
 
 int main(int argc, char *argv[])
 {
-    xp_disk_t buf;
-    int fd;
-    char *strbuf;
+    privcmd_blkmsg_t blkmsg;
+    xp_disk_t        xpd;
 
-    if (argc != 7) {
-       fprintf(stderr,
-               "Usage: xi_physdev_grant <r/rw> <domain> <device> <start sector> <n_sectors> <partition>\n");
+    if ( argc != 7 )
+    {
+       fprintf(stderr, "Usage: xi_physdev_grant <r/rw> <domain> "
+                "<device> <start sector> <n_sectors> <partition>\n");
        return 1;
     }
 
-    buf.mode = 0;
-    if (argv[1][0] == 'r')
-       buf.mode |= 1;
-    else if (argv[1][0] == 'w')
-       buf.mode |= 2;
-    if (argv[1][1] == 'r')
-       buf.mode |= 1;
-    else if (argv[1][1] == 'w')
-       buf.mode |= 2;
-
-    buf.device = atol(argv[3]);
-    buf.start_sect = atol(argv[4]);
-    buf.n_sectors = atol(argv[5]);
-    buf.partition = atol(argv[6]);
-
-    asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[2]);
-    fd = open(strbuf, O_WRONLY);
-    if (fd < 0) {
-       fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno));
-       return 1;
+    xpd.mode = 0;
+    if ( strchr(argv[1], 'r') )
+       xpd.mode |= PHYSDISK_MODE_R;
+    if ( strchr(argv[1], 'w') )
+        xpd.mode |= PHYSDISK_MODE_W;
+
+    xpd.domain     = atol(argv[2]);
+    xpd.device     = xldev_to_physdev(atol(argv[3]));
+    xpd.start_sect = atol(argv[4]);
+    xpd.n_sectors  = atol(argv[5]);
+    xpd.partition  = atol(argv[6]);
+
+    if ( xpd.device == 0 )
+    {
+        ERROR("Unrecognised device");
+        return 1;
     }
-    free(strbuf);
 
-    write(fd, &buf, sizeof(buf));
-    close(fd);
+    blkmsg.op       = XEN_BLOCK_PHYSDEV_GRANT;
+    blkmsg.buf      = &xpd;
+    blkmsg.buf_size = sizeof(xpd);
+
+    if ( do_xen_blkmsg(&blkmsg) < 0 )
+        return 1;
 
     return 0;
 }
index a3dfd8952bb7eb6d52c32c49849557efe1789522..a933e1127671cddff456452735d33d137af668ce 100644 (file)
@@ -1,50 +1,46 @@
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <sys/fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
 
-#include "hypervisor-ifs/block.h"
+#define _GNU_SOURCE
+#include "dom0_defs.h"
 
 int main(int argc, char *argv[])
 {
+    privcmd_blkmsg_t    blkmsg;
     physdisk_probebuf_t buf;
-    int fd;
-    int x;
-    char *strbuf;
+    int                 i;
 
-    if (argc != 2) {
+    if ( argc != 2 )
+    {
        fprintf(stderr, "Usage: xi_phys_probe <domain_nr>\n");
        return 1;
     }
 
-    asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[1]);
-    fd = open(strbuf, O_RDONLY);
-    if (fd < 0) {
-       fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno));
-       return 1;
-    }
-    free(strbuf);
-
     memset(&buf, 0, sizeof(buf));
-    buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
+
     do {
-       buf.n_aces = PHYSDISK_MAX_ACES_PER_REQUEST;
-       read(fd, &buf, sizeof(buf));
-       if (!buf.n_aces)
-           break;
-
-       for (x = 0; x < buf.n_aces; x++) {
-           char read = (buf.entries[x].mode & 1 ? 'r' : ' ');
-           char write = (buf.entries[x].mode & 2 ? 'w' : ' ');
-           printf("%x %x %lx %lx %c%c\n", buf.entries[x].device,
-                  buf.entries[x].partition,
-                  buf.entries[x].start_sect,
-                  buf.entries[x].n_sectors, read, write);
+        buf.domain      = atol(argv[1]);
+       buf.n_aces      = PHYSDISK_MAX_ACES_PER_REQUEST;
+
+        blkmsg.op       = XEN_BLOCK_PHYSDEV_PROBE;
+        blkmsg.buf      = &buf;
+        blkmsg.buf_size = sizeof(buf);
+
+        if ( do_xen_blkmsg(&blkmsg) < 0 )
+            return 1;
+        
+       for ( i = 0; i < buf.n_aces; i++ )
+        {
+           char read = (buf.entries[i].mode & 1 ? 'r' : ' ');
+           char write = (buf.entries[i].mode & 2 ? 'w' : ' ');
+           printf("%x %x %lx %lx %c%c\n", 
+                   physdev_to_xldev(buf.entries[i].device),
+                  buf.entries[i].partition,
+                  buf.entries[i].start_sect,
+                  buf.entries[i].n_sectors, read, write);
        }
+
        buf.start_ind += buf.n_aces;
-    } while (buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST);
+    } 
+    while ( buf.n_aces == PHYSDISK_MAX_ACES_PER_REQUEST );
+
     return 0;
 }
index c39146e889bc533895cf6ae031f79e8616c49615..b018b03a240d6ede3009f269fbaf7ed8f892a745 100644 (file)
@@ -1,40 +1,37 @@
-#define _GNU_SOURCE
-#include <unistd.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/fcntl.h>
-#include <string.h>
-#include <stdlib.h>
 
-#include "hypervisor-ifs/block.h"
+#define _GNU_SOURCE
+#include "dom0_defs.h"
 
 int main(int argc, char *argv[])
 {
-    xp_disk_t buf;
-    int fd;
-    char *strbuf;
+    privcmd_blkmsg_t blkmsg;
+    xp_disk_t        xpd;
 
-    if (argc != 5) {
-       fprintf(stderr,
-               "Usage: xi_physdev_revoke <domain> <device> <start sector> <n_sectors>\n");
+    if ( argc != 5 )
+    {
+       fprintf(stderr, "Usage: xi_physdev_revoke <domain> "
+                "<device> <start sector> <n_sectors>\n");
        return 1;
     }
 
-    buf.device = atol(argv[2]);
-    buf.mode = 0;
-    buf.start_sect = atol(argv[3]);
-    buf.n_sectors = atol(argv[4]);
+    xpd.mode       = 0;
+    xpd.domain     = atol(argv[1]);
+    xpd.device     = xldev_to_physdev(atol(argv[2]));
+    xpd.start_sect = atol(argv[3]);
+    xpd.n_sectors  = atol(argv[4]);
 
-    asprintf(&strbuf, "/proc/xeno/dom%s/phd", argv[1]);
-    fd = open(strbuf, O_WRONLY);
-    if (fd < 0) {
-       fprintf(stderr, "Can\'t open %s: %s.\n", strbuf, strerror(errno));
-       return 1;
+    if ( xpd.device == 0 )
+    {
+        ERROR("Unrecognised device");
+        return 1;
     }
-    free(strbuf);
 
-    write(fd, &buf, sizeof(buf));
-    close(fd);
+    blkmsg.op       = XEN_BLOCK_PHYSDEV_GRANT;
+    blkmsg.buf      = &xpd;
+    blkmsg.buf_size = sizeof(xpd);
+
+    if ( do_xen_blkmsg(&blkmsg) < 0 )
+        return 1;
 
     return 0;
 }
diff --git a/tools/internal/xi_sched_domain.c b/tools/internal/xi_sched_domain.c
new file mode 100644 (file)
index 0000000..c8d921f
--- /dev/null
@@ -0,0 +1,32 @@
+
+#include "hypervisor-ifs/dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+static char *argv0 = "internal_domain_sched_domain";
+
+int main(int argc, char **argv)
+{
+    dom0_op_t op;
+
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
+
+    if ( argc != 6 ) 
+    {
+        fprintf(stderr, "Usage: %s <domain> <mcu_adv> "
+                "<warp> <warpl> <warpu>\n", argv0);
+        return 1;
+    }
+
+    op.cmd = DOM0_ADJUSTDOM;
+    op.u.adjustdom.domain  = atoi(argv[1]);
+    op.u.adjustdom.mcu_adv = atol(argv[1]);
+    op.u.adjustdom.warp    = atol(argv[1]);
+    op.u.adjustdom.warpl   = atol(argv[1]);
+    op.u.adjustdom.warpu   = atol(argv[1]);
+    if ( do_dom0_op(&op) < 0 )
+        return 1;
+
+    return 0;
+}
diff --git a/tools/internal/xi_sched_global.c b/tools/internal/xi_sched_global.c
new file mode 100644 (file)
index 0000000..0c07455
--- /dev/null
@@ -0,0 +1,27 @@
+
+#include "hypervisor-ifs/dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+static char *argv0 = "internal_domain_sched_global";
+
+int main(int argc, char **argv)
+{
+    dom0_op_t op;
+
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
+
+    if ( argc != 2 ) 
+    {
+        fprintf(stderr, "Usage: %s <ctxt allowance>\n", argv0);
+        return 1;
+    }
+
+    op.cmd = DOM0_BVTCTL;
+    op.u.bvtctl.ctx_allow = atol(argv[1]);
+    if ( do_dom0_op(&op) < 0 )
+        return 1;
+
+    return 0;
+}
index c6826c487442ecbff7d534a994d17a6224628bab..b21cc84f9f5803e320444373c2e4051b17872502 100644 (file)
@@ -1,77 +1,37 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-#include <string.h>
 
-#include "dom0_ops.h"
+#include "hypervisor-ifs/dom0_ops.h"
 #include "dom0_defs.h"
 #include "mem_defs.h"
 
-/***********************************************************************/
-
 static char *argv0 = "internal_domain_start";
 
-static void ERROR (char *message)
-{
-  fprintf (stderr, "%s: %s\n", argv0, message);
-  exit (-1);
-}
-
-static void PERROR (char *message)
-{
-  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
-  exit (-1);
-}
-
-/***********************************************************************/
-
 static int start_domain(int id)
 {
-    char cmd_path[MAX_PATH];
-    dom0_op_t dop;
-    int cmd_fd;
-
-    /* Set up the DOM0_STARTDOMAIN command */
-    dop.cmd = DOM0_STARTDOMAIN;
-    dop.u.meminfo.domain = id;
+    int err;
+    dom0_op_t op;
 
-    /* open the /proc command interface */
-    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
-    cmd_fd = open(cmd_path, O_WRONLY);
-    if(cmd_fd < 0){
-        PERROR ("Count not open PROC_CMD interface");
-    }
+    op.cmd = DOM0_STARTDOMAIN;
+    op.u.meminfo.domain = id;
 
-    /* Issue the command */
-    write(cmd_fd, &dop, sizeof(dom0_op_t));
-    close(cmd_fd);
+    err = do_dom0_op(&op);
 
-    return 0;
+    return (err < 0) ? -1 : 0;
 }    
 
-/***********************************************************************/
-
 int main(int argc, char **argv)
 {
-  int rc;
+    int rc;
 
-  if (argv[0] != NULL) 
-    {
-      argv0 = argv[0];
-    }
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
 
-  if(argc != 2
+    if ( argc != 2 
     {
-      fprintf (stderr, "Usage: %s <domain-id>\n", argv0);
-      return -1;
+        fprintf(stderr, "Usage: %s <domain-id>\n", argv0);
+        return 1;
     }
 
-  rc = start_domain(atol(argv[1]));
+    rc = start_domain(atol(argv[1]));
 
-  return rc;
+    return (rc != 0) ? 1 : 0;
 }
index 6f2437ca14dc0c129d1df14e8cc890f9ec6e9999..5cd732df3a3f143bcefe3e78ab8215610c31507c 100644 (file)
@@ -1,79 +1,36 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdlib.h>
-
-#include "dom0_ops.h"
+#include "hypervisor-ifs/dom0_ops.h"
 #include "dom0_defs.h"
 #include "mem_defs.h"
 
-/***********************************************************************/
-
 static char *argv0 = "internal_domain_stop";
 
-static void ERROR (char *message)
-{
-  fprintf (stderr, "%s: %s\n", argv0, message);
-  exit (-1);
-}
-
-static void PERROR (char *message)
-{
-  fprintf (stderr, "%s: %s (%s)\n", argv0, message, strerror(errno));
-  exit (-1);
-}
-
-/***********************************************************************/
-
 static int stop_domain(int id)
 {
-    dom0_newdomain_t * dom_data;
-    char cmd_path[MAX_PATH];
-    char dom_id_path[MAX_PATH];
-    dom0_op_t dop;
-    int cmd_fd;
-    int id_fd;
+    int err;
+    dom0_op_t op;
 
-    /* Set up the DOM0_STOPDOMAIN command */
-    dop.cmd = DOM0_STOPDOMAIN;
-    dop.u.meminfo.domain = id;
-
-    /* open the /proc command interface */
-    sprintf(cmd_path, "%s%s%s%s", "/proc/", PROC_XENO_ROOT, "/", PROC_CMD);
-    cmd_fd = open(cmd_path, O_WRONLY);
-    if(cmd_fd < 0){
-        PERROR ("Count not open PROC_CMD interface");
-    }
+    op.cmd = DOM0_STOPDOMAIN;
+    op.u.meminfo.domain = id;
 
-    /* Issue the command */
-    write(cmd_fd, &dop, sizeof(dom0_op_t));
-    close(cmd_fd);
+    err = do_dom0_op(&op);
 
-    return 0;
+    return (err < 0) ? -1 : 0;
 }    
 
-/***********************************************************************/
-
 int main(int argc, char **argv)
 {
-  int rc;
+    int rc;
 
-  if (argv[0] != NULL) 
-    {
-      argv0 = argv[0];
-    }
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
 
-  if(argc != 2
+    if ( argc != 2 
     {
-      fprintf (stderr, "Usage: %s <domain-id>\n", argv0);
-      return -1;
+        fprintf(stderr, "Usage: %s <domain-id>\n", argv0);
+        return 1;
     }
 
-  rc = stop_domain(atol(argv[1]));
+    rc = stop_domain(atol(argv[1]));
 
-  return rc;
+    return (rc != 0) ? 1 : 0;
 }
diff --git a/tools/internal/xi_usage.c b/tools/internal/xi_usage.c
new file mode 100644 (file)
index 0000000..3cd6143
--- /dev/null
@@ -0,0 +1,64 @@
+
+#include "hypervisor-ifs/dom0_ops.h"
+#include "dom0_defs.h"
+#include "mem_defs.h"
+
+static char *argv0 = "internal_domain_usage";
+
+int main(int argc, char **argv)
+{
+    dom0_op_t    op;
+    network_op_t netop;
+    int          i, domain, vifs[32];
+
+    if ( argv[0] != NULL ) 
+        argv0 = argv[0];
+
+    if ( argc != 2 ) 
+    {
+        fprintf(stderr, "Usage: %s <domain-id>\n", argv0);
+        return 1;
+    }
+
+    domain = atol(argv[1]);
+
+    op.cmd                 = DOM0_GETDOMAININFO;
+    op.u.getdominfo.domain = domain;
+    if ( do_dom0_op(&op) < 0 )
+        return 1;
+
+    printf("cpu%d: %lld\n", 
+           op.u.getdominfo.processor,
+           op.u.getdominfo.cpu_time);
+
+    if ( mlock(vifs, sizeof(vifs)) != 0 )
+    {
+        PERROR("Could not lock memory for network query buffer");
+        return 1;
+    }
+
+    netop.cmd = NETWORK_OP_VIFQUERY;
+    netop.u.vif_query.domain = domain;
+    netop.u.vif_query.buf    = vifs;
+    if ( do_network_op(&netop) < 0 )
+        return 1;
+
+    for ( i = 1; i <= vifs[0]; i++ )
+    {
+        netop.cmd = NETWORK_OP_VIFGETINFO;
+        netop.u.vif_getinfo.domain = domain;
+        netop.u.vif_getinfo.vif    = vifs[i];
+        if ( do_network_op(&netop) < 0 )
+            return 1;
+
+        printf("vif%d: sent %lld bytes (%lld packets) "
+               "received %lld bytes (%lld packets)\n",
+               vifs[i],
+               netop.u.vif_getinfo.total_bytes_sent,
+               netop.u.vif_getinfo.total_packets_sent,
+               netop.u.vif_getinfo.total_bytes_received,
+               netop.u.vif_getinfo.total_packets_received);
+    }
+
+    return 0;
+}
index feac666bb63db12e756d1cf6ce78fc07c3a8daee..0da845984bfa7ee412756de778e60a8933f6dc25 100755 (executable)
@@ -16,10 +16,10 @@ then
 fi
 
 #outbound rule:
-echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/vfr
+echo "ADD ACCEPT srcaddr=$3 srcaddrmask=255.255.255.255 srcdom=$1 srcidx=$2 dst=PHYS proto=any" > /proc/xeno/vfr
 
 #inbound rule:
-echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/vfr
+echo "ADD ACCEPT dstaddr=$3 dstaddrmask=255.255.255.255 src=ANY dstdom=$1 dstidx=$2 proto=any" > /proc/xeno/vfr
 
 #----] done.
 
index 281fb509b967f2a8671128c16b952daaf15990fd..9e6269b294396b4eacf75317ce68912da30ef866 100644 (file)
@@ -146,9 +146,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
         ret = p->domain;
         
         op.u.newdomain.domain = ret;
-        op.u.newdomain.pg_head = 
-            list_entry(p->pg_head.next, struct pfn_info, list) -
-            frame_table;
         copy_to_user(u_dom0_op, &op, sizeof(op));
 
     exit_create:
@@ -189,16 +186,38 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
     case DOM0_GETMEMLIST:
     {
         int i;
-        unsigned long pfn = op.u.getmemlist.start_pfn;
+        struct task_struct * p = find_domain_by_id(op.u.getmemlist.domain);
+        unsigned long max_pfns = op.u.getmemlist.max_pfns;
+        unsigned long pfn;
         unsigned long *buffer = op.u.getmemlist.buffer;
         struct list_head *list_ent;
 
-        for ( i = 0; i < op.u.getmemlist.num_pfns; i++ )
+        ret = -EINVAL;
+        if ( p != NULL )
         {
-            /* XXX We trust DOM0 to give us a safe buffer. XXX */
-            *buffer++ = pfn;
-            list_ent = frame_table[pfn].list.next;
+            list_ent = p->pg_head.next;
             pfn = list_entry(list_ent, struct pfn_info, list) - frame_table;
+            
+            for ( i = 0; (i < max_pfns) && (list_ent != &p->pg_head); i++ )
+            {
+                if ( put_user(pfn, buffer) )
+                {
+                    ret = -EFAULT;
+                    goto out_getmemlist;
+                }
+                buffer++;
+                list_ent = frame_table[pfn].list.next;
+                pfn = list_entry(list_ent, struct pfn_info, list) - 
+                    frame_table;
+            }
+
+            op.u.getmemlist.num_pfns = i;
+            copy_to_user(u_dom0_op, &op, sizeof(op));
+
+            ret = 0;
+
+        out_getmemlist:
+            put_task_struct(p);
         }
     }
     break;
@@ -227,9 +246,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
             op.u.getdominfo.state       = p->state;
             op.u.getdominfo.hyp_events  = p->hyp_events;
             op.u.getdominfo.mcu_advance = p->mcu_advance;
-            op.u.getdominfo.pg_head     = 
-                list_entry(p->pg_head.next, struct pfn_info, list) -
-                frame_table;
             op.u.getdominfo.tot_pages   = p->tot_pages;
             op.u.getdominfo.cpu_time    = p->cpu_time;
         }
index 06e67e7dc578b5523e1620a5d0b0488f7b795de1..90cf1cd161358923cdf8279b02af984dd6c8a51f 100644 (file)
@@ -462,6 +462,7 @@ static unsigned long alloc_page_from_domain(unsigned long * cur_addr,
  * userspace dom0 and final setup is being done by final_setup_guestos.
  */
 int setup_guestos(struct task_struct *p, dom0_newdomain_t *params, 
+                  unsigned int num_vifs,
                   char *phy_data_start, unsigned long data_len, 
                  char *cmdline, unsigned long initrd_len)
 {
@@ -689,7 +690,7 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
     }
 
     /* Add virtual network interfaces and point to them in startinfo. */
-    while (params->num_vifs-- > 0) {
+    while (num_vifs-- > 0) {
         net_vif = create_net_vif(dom);
         shared_rings = net_vif->shared_rings;
         if (!shared_rings) panic("no network ring!\n");
index d403717e556a1555125c326456a6d6ccc2de71de..999c88fd4bd517ae466cd28f6d5221a728de7600 100644 (file)
@@ -197,9 +197,7 @@ void cmain (unsigned long magic, multiboot_info_t *mbi)
     start_of_day();
 
     /* Create initial domain 0. */
-    dom0_params.num_vifs  = 1;
     dom0_params.memory_kb = opt_dom0_mem;
-
     new_dom = do_newdomain(0, 0);
     if ( new_dom == NULL ) panic("Error creating domain 0\n");
 
@@ -209,7 +207,7 @@ void cmain (unsigned long magic, multiboot_info_t *mbi)
      * present, is an initrd ramdisk
      */
     if ( setup_guestos(new_dom, 
-                       &dom0_params, 
+                       &dom0_params, 1,
                        (char *)MAX_DIRECTMAP_ADDRESS, 
                        mod[mbi->mods_count-1].mod_end - mod[0].mod_start,
                        __va(mod[0].string),
index 30cdf81441b644451a666331815fe5b91f4ec0bf..f8526c1854cfc0eaac3b0be92a87dcb3e3e26b97 100644 (file)
@@ -8,7 +8,6 @@
  * Copyright (c) 2002-2003, A K Warfield and K A Fraser
  */
 
-#include <hypervisor-ifs/network.h>
 #include <xeno/sched.h>
 #include <xeno/errno.h>
 #include <xeno/init.h>
@@ -20,6 +19,7 @@
 #include <xeno/in.h>
 #include <asm/domain_page.h>
 #include <asm/io.h>
+#include <hypervisor-ifs/network.h>
 
 net_rule_ent_t *net_rule_list;                      /* global list of rules */
 kmem_cache_t *net_vif_cache;                        
@@ -222,7 +222,7 @@ int vif_query(vif_query_t *vq)
     if ( !(p = find_domain_by_id(vq->domain)) ) {
         buf[0] = -1;
         copy_to_user(vq->buf, buf, sizeof(int));
-        return -ENOSYS;
+        return -ESRCH;
     }
 
     for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
@@ -524,12 +524,13 @@ long do_network_op(network_op_t *u_network_op)
 {
     long ret=0;
     network_op_t op;
-    
+
     if ( current->domain != 0 )
         return -EPERM;
 
     if ( copy_from_user(&op, u_network_op, sizeof(op)) )
         return -EFAULT;
+
     switch ( op.cmd )
     {
 
@@ -566,6 +567,7 @@ long do_network_op(network_op_t *u_network_op)
     {
         ret = vif_query(&op.u.vif_query);
     }
+    break;
     
     default:
         ret = -ENOSYS;
index b437acec26f54239a6f06c33ea1eb6df6793454d..e61786609085e47f9da642b9351262da41b65242 100644 (file)
 
 typedef struct dom0_newdomain_st 
 {
-    unsigned int domain;    // return parameter
+    /* IN parameters. */
     unsigned int memory_kb; 
-    unsigned int num_vifs;  // temporary
-    unsigned long pg_head;  // return parameter
     char name[MAX_DOMAIN_NAME];
+    /* OUT parameters. */
+    unsigned int domain; 
 } dom0_newdomain_t;
 
 typedef struct dom0_killdomain_st
@@ -41,14 +41,17 @@ typedef struct dom0_killdomain_st
 
 typedef struct dom0_getmemlist_st
 {
-    unsigned long start_pfn;
+    /* IN variables. */
+    unsigned int  domain;
+    unsigned long max_pfns;
+    void         *buffer;
+    /* OUT variables. */
     unsigned long num_pfns;
-    void *buffer;
 } dom0_getmemlist_t;
 
 typedef struct domain_launch
 {
-    unsigned int domain;
+    unsigned int  domain;
     unsigned long l2_pgt_addr;
     unsigned long virt_load_addr;
     unsigned long virt_shinfo_addr;
@@ -75,14 +78,15 @@ typedef struct dom0_adjustdom_st
 
 typedef struct dom0_getdominfo_st
 {
-    unsigned int domain;          /* All returns except domain */
+    /* IN variables. */
+    unsigned int domain;
+    /* OUT variables. */
     char name[MAX_DOMAIN_NAME];
     int processor;
     int has_cpu;
     int state;
     int hyp_events;
     unsigned long mcu_advance;
-    unsigned long pg_head;
     unsigned int tot_pages;
     long long cpu_time;
 } dom0_getdominfo_t;
@@ -93,7 +97,6 @@ typedef struct dom0_iopl_st
     unsigned int iopl;
 } dom0_iopl_t;
 
-#ifndef NO_DOM0_OP_T
 typedef struct dom0_op_st
 {
     unsigned long cmd;
@@ -110,6 +113,5 @@ typedef struct dom0_op_st
     }
     u;
 } dom0_op_t;
-#endif
 
 #endif
index 09703df92504fcd188cb47aedd5eb9ddaf9a941d..d2e57cd0fb22bab9bad0d31898af76e0fb5763ce 100644 (file)
@@ -12,9 +12,6 @@
 #ifndef __RING_H__
 #define __RING_H__
 
-#include <linux/types.h>
-
-
 typedef struct tx_req_entry_st
 {
     unsigned short id;
index 351afa5e8dcbbe484296d64b9dafd7245c813e1a..ffec7d427b34d1c7d34e21aa13a26e7141da52be 100644 (file)
@@ -226,7 +226,7 @@ extern struct task_struct first_task_struct;
 
 extern struct task_struct *do_newdomain(unsigned int dom_id, unsigned int cpu);
 extern int setup_guestos(
-    struct task_struct *p, dom0_newdomain_t *params,
+    struct task_struct *p, dom0_newdomain_t *params, unsigned int num_vifs,
     char *data_start, unsigned long data_len, 
     char *cmdline, unsigned long initrd_len);
 extern int final_setup_guestos(struct task_struct *p, dom_meminfo_t *);
index 6565e93645e57d5958b5411c7185b64eed0c2c6c..89777dc9e9be82b18bbe2714da6440070e320c48 100644 (file)
@@ -48,14 +48,18 @@ HEAD := arch/xeno/kernel/head.o arch/xeno/kernel/init_task.o
 
 SUBDIRS += arch/xeno/kernel arch/xeno/mm arch/xeno/lib
 SUBDIRS += arch/xeno/drivers/console arch/xeno/drivers/network
-SUBDIRS += arch/xeno/drivers/dom0 arch/xeno/drivers/block
-SUBDIRS += arch/xeno/drivers/balloon
+SUBDIRS += arch/xeno/drivers/block arch/xeno/drivers/balloon
+ifdef CONFIG_XENO_PRIV
+SUBDIRS += arch/xeno/drivers/dom0 
+endif
 
 CORE_FILES += arch/xeno/kernel/kernel.o arch/xeno/mm/mm.o
 CORE_FILES += arch/xeno/drivers/console/con.o
 CORE_FILES += arch/xeno/drivers/block/blk.o
 CORE_FILES += arch/xeno/drivers/network/net.o
+ifdef CONFIG_XENO_PRIV
 CORE_FILES += arch/xeno/drivers/dom0/dom0.o
+endif
 CORE_FILES += arch/xeno/drivers/balloon/balloon_driver.o
 LIBS := $(TOPDIR)/arch/xeno/lib/lib.a $(LIBS) $(TOPDIR)/arch/xeno/lib/lib.a
 
index 6ae2bca111469efb5ee6995796f87692658eb5df..a25e336457603625e29405914e070fa6432cc81d 100644 (file)
@@ -12,6 +12,11 @@ define_bool CONFIG_SBUS n
 
 define_bool CONFIG_UID16 y
 
+mainmenu_option next_comment
+comment 'Privileged guest OS'
+bool 'Support for privileged operations (domain 0)' CONFIG_XENO_PRIV
+endmenu
+
 mainmenu_option next_comment
 comment 'Code maturity level options'
 bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
index 53314262a9596deca25c1b24b674776e1abad5e7..4bcc51c3faf94003b464767cf2a8ff170b23649e 100644 (file)
@@ -7,6 +7,11 @@ CONFIG_ISA=y
 # CONFIG_SBUS is not set
 CONFIG_UID16=y
 
+#
+# Privileged guest OS
+#
+CONFIG_XENO_PRIV=y
+
 #
 # Code maturity level options
 #
index c6997d271768aa521877ed63b1a9936a83cb00b2..6423104172490e2d5889bca4f9b09141cc4ab97a 100644 (file)
@@ -1,3 +1,3 @@
 O_TARGET := blk.o
-obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o xl_segment_proc.o xl_physdisk_proc.o
+obj-y := xl_block.o xl_ide.o xl_scsi.o xl_segment.o xl_segment_proc.o
 include $(TOPDIR)/Rules.make
index dbaffb76d915e5c25ca2e3246a35fb2d44704b25..565b07238d7e599f1ad9c9c2d41024fa582fdc97 100644 (file)
@@ -43,6 +43,31 @@ static inline void signal_requests_to_xen(void)
     HYPERVISOR_block_io_op();
 }
 
+
+inline kdev_t physdev_to_xldev(unsigned short physdev)
+{
+    switch (physdev & XENDEV_TYPE_MASK) {
+    case XENDEV_IDE:
+        if ( (physdev & XENDEV_IDX_MASK) < XLIDE_DEVS_PER_MAJOR) {
+           return MKDEV(XLIDE_MAJOR_0,
+                        (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
+       } else if ( (physdev & XENDEV_IDX_MASK) < (XLIDE_DEVS_PER_MAJOR * 2)) {
+           return MKDEV(XLIDE_MAJOR_1,
+                        (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
+       }
+       break;
+    case XENDEV_SCSI:
+       return MKDEV(XLSCSI_MAJOR,
+                    (physdev & XENDEV_IDX_MASK) << XLSCSI_PARTN_SHIFT);
+    case XENDEV_VIRTUAL:
+       return MKDEV(XLVIRT_MAJOR,
+                    (physdev & XENDEV_IDX_MASK) << XLVIRT_PARTN_SHIFT);
+    }
+
+    return 0;
+}
+
+
 /* Convert from a XenoLinux major device to the Xen-level 'physical' device */
 inline unsigned short xldev_to_physdev(kdev_t xldev) 
 {
@@ -69,8 +94,6 @@ inline unsigned short xldev_to_physdev(kdev_t xldev)
         break;
     } 
 
-    if ( physdev == 0 ) BUG();
-
     return physdev;
 }
 
index ac7e7ae97a52e0c3446f4e9be236f76fee164249..00056bf09ee78ec6cb69566575e777d9f822a041 100644 (file)
@@ -104,4 +104,7 @@ extern struct gendisk *xlscsi_gendisk;
 extern int  xlsegment_hwsect(int minor); 
 extern struct gendisk *xlsegment_gendisk;
 
+extern unsigned short xldev_to_physdev(kdev_t xldev);
+extern kdev_t physdev_to_xldev(unsigned short physdev);
+
 #endif /* __XL_BLOCK_H__ */
diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/block/xl_physdisk_proc.c
deleted file mode 100644 (file)
index cda22db..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* We stuff the domain number into the proc_dir_entry data pointer. */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <asm/errno.h>
-#include <linux/slab.h>
-#include <asm/hypervisor-ifs/block.h>
-#include <asm/uaccess.h>
-#include <linux/proc_fs.h>
-
-#include "xl_block.h"
-
-extern int xenolinux_control_msg(int operration, char *buffer, int size);
-extern unsigned short xldev_to_physdev(kdev_t xldev);
-
-dev_t physdev_to_xldev(unsigned short physdev)
-{
-    switch (physdev & XENDEV_TYPE_MASK) {
-    case XENDEV_IDE:
-        if ( (physdev & XENDEV_IDX_MASK) < XLIDE_DEVS_PER_MAJOR) {
-           return MKDEV(XLIDE_MAJOR_0,
-                        (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
-       } else if ( (physdev & XENDEV_IDX_MASK) < (XLIDE_DEVS_PER_MAJOR * 2)) {
-           return MKDEV(XLIDE_MAJOR_1,
-                        (physdev & XENDEV_IDX_MASK) << XLIDE_PARTN_SHIFT);
-       }
-       break;
-    case XENDEV_SCSI:
-       return MKDEV(XLSCSI_MAJOR,
-                    (physdev & XENDEV_IDX_MASK) << XLSCSI_PARTN_SHIFT);
-    case XENDEV_VIRTUAL:
-       return MKDEV(XLVIRT_MAJOR,
-                    (physdev & XENDEV_IDX_MASK) << XLVIRT_PARTN_SHIFT);
-    }
-    printk(KERN_ALERT "Unrecognised xl device: %x\n", physdev);
-    BUG();
-    return -1;
-}
-
-static ssize_t proc_read_phd(struct file *file, char *buff, size_t size,
-                            loff_t * off)
-{
-    physdisk_probebuf_t *buf;
-    int res;
-    struct proc_dir_entry *pde;
-    int x;
-
-    if (size != sizeof(physdisk_probebuf_t))
-       return -EINVAL;
-
-    buf = kmalloc(sizeof(physdisk_probebuf_t), GFP_KERNEL);
-    if (!buf)
-       return -ENOMEM;
-
-    pde = file->f_dentry->d_inode->u.generic_ip;
-    buf->domain = (int) pde->data;
-
-    /* The offset reported by lseek and friends doesn't have to be in
-       bytes, and it's marginally easier to say that it's in records, so
-       that's what we do. */
-    buf->start_ind = *off;
-    res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_PROBE, (void *) buf,
-                               sizeof(physdisk_probebuf_t));
-    *off += buf->n_aces;
-
-    if (res)
-       res = -EINVAL;
-    else {
-       for (x = 0; x < buf->n_aces; x++)
-           buf->entries[x].device =
-               physdev_to_xldev(buf->entries[x].device);
-       res = sizeof(physdisk_probebuf_t);
-       if (copy_to_user(buff, buf, sizeof(physdisk_probebuf_t))) {
-           res = -EFAULT;
-       }
-    }
-    kfree(buf);
-    return res;
-}
-
-static int proc_write_phd(struct file *file, const char *buffer,
-                         size_t count, loff_t * ignore)
-{
-    char *local;
-    int res;
-    xp_disk_t *xpd;
-    struct proc_dir_entry *pde;
-
-    if (count != sizeof(xp_disk_t))
-       return -EINVAL;
-
-    local = kmalloc(count + 1, GFP_KERNEL);
-    if (!local)
-       return -ENOMEM;
-    if (copy_from_user(local, buffer, count)) {
-       res = -EFAULT;
-       goto out;
-    }
-
-    xpd = (xp_disk_t *) local;
-
-    pde = file->f_dentry->d_inode->u.generic_ip;
-    xpd->domain = (int) pde->data;
-    xpd->device = xldev_to_physdev(xpd->device);
-
-    res = xenolinux_control_msg(XEN_BLOCK_PHYSDEV_GRANT, local, count);
-    if (res == 0)
-       res = count;
-    else
-       res = -EINVAL;
-  out:
-    kfree(local);
-    return res;
-}
-
-struct file_operations dom0_phd_fops = {
-  read:proc_read_phd,
-  write:proc_write_phd
-};
index d1b12e203d73a74ab9dba6584d2a2b1cf5c439b5..464707362a8a773ad96e45b2de99e140bc7f6653 100644 (file)
@@ -12,9 +12,6 @@
 
 static struct proc_dir_entry *vhd;
 
-extern unsigned short xldev_to_physdev(kdev_t xldev);
-extern dev_t physdev_to_xldev(unsigned short physdev);
-
 static void *proc_vhd_next(struct seq_file *s, void *v, loff_t *pos)
 {
     xen_segment_info_t *data;
@@ -310,11 +307,13 @@ static struct file_operations proc_vhd_operations = {
 
 int __init xlseg_proc_init(void)
 {
-    vhd = create_proc_entry("xeno/dom0/vhd", 0600, NULL);
-    if (vhd == NULL)
-    {
+    if ( !(start_info.flags & SIF_PRIVILEGED) )
+        return 0;
+
+    vhd = create_proc_entry("xeno/vhd", 0600, NULL);
+    if ( vhd == NULL )
         panic ("xlseg_init: unable to create vhd proc entry\n");
-    }
+
     vhd->data       = NULL;
     vhd->proc_fops  = &proc_vhd_operations;
     vhd->owner      = THIS_MODULE;
index eeb34138424989647992f3dd792060db2e1ef0a6..9030801f1423a12df2421e7d1325acaf1ffb5b71 100644 (file)
@@ -1,3 +1,3 @@
 O_TARGET := dom0.o
-obj-y := dom0_memory.o dom0_core.o vfr.o sched_ops.o
+obj-y := dom0_core.o vfr.o
 include $(TOPDIR)/Rules.make
diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_block.c
deleted file mode 100644 (file)
index 97d4a65..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * domain 0 block driver interface
- *
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-static int __init init_module(void)
-{
-  request_module("xl_block");
-  printk("Successfully installed domain 0 block interface\n");
-
-
-  return 0;
-}
-
-static void __exit cleanup_module(void)
-{
-  printk("Successfully de-installed domain-0 block interface\n");
-  return 0;
-}
-
-module_init(init_module);
-module_exit(cleanup_module);
index c31c2d2410a798d7a6e1cacfffcf10026a432f1f..837dd6dad044f3fd0a2f2359b692813d6b8611cc 100644 (file)
@@ -3,7 +3,7 @@
  * 
  * Interface to privileged domain-0 commands.
  * 
- * Copyright (c) 2002, K A Fraser, B Dragovic
+ * Copyright (c) 2002-2003, K A Fraser, B Dragovic
  */
 
 #include <linux/config.h>
@@ -14,7 +14,6 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/proc_fs.h>
-
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/tlb.h>
-#include <asm/dom0.h>
-
-#include "dom0_ops.h"
-
-#define MAP_DISCONT 1
+#include <asm/proc_cmd.h>
+#include <asm/hypervisor-ifs/dom0_ops.h>
 
-/* Private proc-file data structures. */
-typedef struct proc_data {
-    unsigned int domain;
-    unsigned long map_size;
-} dom_procdata_t;
-
-/* XXX this certainly shouldn't be here. */
-extern struct file_operations dom0_phd_fops;
+#include "../block/xl_block.h"
 
 struct proc_dir_entry *xeno_base;
-static struct proc_dir_entry *dom0_cmd_intf;
-static struct proc_dir_entry *dom_list_intf;
+static struct proc_dir_entry *privcmd_intf;
 
-int direct_unmap(struct mm_struct *, unsigned long, unsigned long);
-unsigned long direct_mmap(unsigned long phys_addr, unsigned long size, 
-                         pgprot_t prot, int flag, int tot_pages);
-struct list_head * find_direct(struct list_head *, unsigned long);
 
-static ssize_t dom_usage_read(struct file * file, char * buff, size_t size, loff_t * off)
+static int privcmd_ioctl(struct inode *inode, struct file *file,
+                         unsigned int cmd, unsigned long data)
 {
-    char str[256];
-    int vifs[32];
-    dom0_op_t op;
-    network_op_t netop;
-    int i, end;
-    unsigned int domain;
-    static int finished = 0;
+    int ret = 0;
 
-    if ( finished )
+    switch ( cmd )
     {
-        finished = 0;
-        return 0;
-    }
-
-    domain = (unsigned int)
-        ((struct proc_dir_entry *)file->f_dentry->d_inode->u.generic_ip)->data;
-    op.cmd = DOM0_GETDOMAININFO;
-
-    op.u.getdominfo.domain = domain;
-
-    (void) HYPERVISOR_dom0_op(&op);
-
-    end = snprintf(str, 256, "cpu: %lld\n", op.u.getdominfo.cpu_time);
-
-    netop.cmd = NETWORK_OP_VIFQUERY;
-    netop.u.vif_query.domain = domain;
-    netop.u.vif_query.buf = vifs;
-
-    (void) HYPERVISOR_network_op(&netop);
-
-    for(i = 1; i <= vifs[0]; i++) {
-        netop.cmd = NETWORK_OP_VIFGETINFO;
-        netop.u.vif_getinfo.domain = domain;
-        netop.u.vif_getinfo.vif = vifs[i];
-
-        (void) HYPERVISOR_network_op(&netop);
-
-        end += snprintf(str + end, 255 - end,
-                        "vif%d: sent %lld bytes (%lld packets) "
-                        "received %lld bytes (%lld packets)\n",
-                        vifs[i],
-                        netop.u.vif_getinfo.total_bytes_sent,
-                        netop.u.vif_getinfo.total_packets_sent,
-                        netop.u.vif_getinfo.total_bytes_received,
-                        netop.u.vif_getinfo.total_packets_received);
-    }
-
-    if (*off >= end + 1) return 0;
-    
-    copy_to_user(buff, str, end);
-
-    finished = 1;
-
-    return end + 1;
-}
-
-static struct file_operations dom_usage_ops = {
-    read:    dom_usage_read
-};
-
-
-static void create_proc_dom_entries(int dom)
-{
-    struct proc_dir_entry * dir;
-    dom_procdata_t * dom_data;
-    char dir_name[16];
-    struct proc_dir_entry * file;
-
-    sprintf(dir_name, "dom%d", dom);
-
-    dom_data = (dom_procdata_t *)kmalloc(sizeof(dom_procdata_t), GFP_KERNEL);
-    dom_data->domain = dom;
-
-    dir = proc_mkdir(dir_name, xeno_base);
-    dir->data = dom_data;
-    
-    file = create_proc_entry("usage", 0600, dir);
-    if (file != NULL)
+    case IOCTL_PRIVCMD_HYPERCALL:
     {
-        file->owner         = THIS_MODULE;
-        file->nlink         = 1;
-        file->proc_fops     = &dom_usage_ops;
-        file->data          = (void *) dom;
+        privcmd_hypercall_t hypercall;
+        if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
+            return -EFAULT;
+        __asm__ __volatile__ (
+            "pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
+            "movl  4(%%eax),%%ebx ;"
+            "movl  8(%%eax),%%ecx ;"
+            "movl 12(%%eax),%%edx ;"
+            "movl 16(%%eax),%%esi ;"
+            "movl 20(%%eax),%%edi ;"
+            "movl   (%%eax),%%eax ;"
+            TRAP_INSTR "; "
+            "popl %%edi; popl %%esi; popl %%edx; popl %%ecx; popl %%ebx"
+            : "=a" (ret) : "0" (&hypercall) : "memory" );
     }
+    break;
 
-    file = create_proc_entry("phd", 0600, dir);
-    if (file != NULL)
+    case IOCTL_PRIVCMD_BLKMSG:
     {
-        file->owner         = THIS_MODULE;
-        file->nlink         = 1;
-        file->proc_fops     = &dom0_phd_fops;
-        file->data          = (void *) dom;
+        privcmd_blkmsg_t blkmsg;
+        char            *kbuf;
+        int              ret;
+        if ( copy_from_user(&blkmsg, (void *)data, sizeof(blkmsg)) )
+            return -EFAULT;
+        if ( blkmsg.buf_size > PAGE_SIZE )
+            return -EINVAL;
+        if ( (kbuf = kmalloc(blkmsg.buf_size, GFP_KERNEL)) == NULL )
+            return -ENOMEM;
+        if ( copy_from_user(kbuf, blkmsg.buf, blkmsg.buf_size) ) {
+            kfree(kbuf);
+            return -EFAULT;
+        }
+        ret = xenolinux_control_msg((int)blkmsg.op, kbuf, blkmsg.buf_size);
+        if ( ret != 0 ) {
+            kfree(kbuf);
+            return ret;
+        }
+        if ( copy_to_user(blkmsg.buf, kbuf, blkmsg.buf_size) ) {
+            kfree(kbuf);
+            return -EFAULT;
+        }
+        kfree(kbuf);
     }
-}
-
-/***********************************************************************
- *
- * Implementation of /proc/xeno/domains
- */
-
-static dom0_op_t proc_domains_op;
-static int proc_domains_finished;
-static DECLARE_MUTEX(proc_xeno_domains_lock);
-
-static void *xeno_domains_next(struct seq_file *s, void *v, loff_t *pos)
-{
-    int ret;
+    break;
+    
+    case IOCTL_PRIVCMD_LINDEV_TO_XENDEV:
+        ret = (int)xldev_to_physdev((kdev_t)data);
 
-    if ( pos != NULL )
-        ++(*pos); 
+    case IOCTL_PRIVCMD_XENDEV_TO_LINDEV:
+        ret = (int)physdev_to_xldev((unsigned short)data);
 
-    if ( !proc_domains_finished ) 
+    default:
     {
-        proc_domains_op.u.getdominfo.domain++;
-        ret = HYPERVISOR_dom0_op(&proc_domains_op);
-        if ( ret < 0 ) 
-            proc_domains_finished = 1;
+        ret = -EINVAL;
     }
-  
-    return (proc_domains_finished) ? NULL : &proc_domains_op;
-}
-
-static void *xeno_domains_start(struct seq_file *s, loff_t *ppos)
-{ 
-    loff_t pos = *ppos;
-  
-    down (&proc_xeno_domains_lock);
-    proc_domains_op.cmd = DOM0_GETDOMAININFO;
-    proc_domains_op.u.getdominfo.domain = 0;
-    (void)HYPERVISOR_dom0_op(&proc_domains_op);
-    proc_domains_finished = 0;
-  
-    while (pos > 0) {
-        pos --;
-        xeno_domains_next (s, NULL, NULL);
+    break;
     }
-  
-    return (proc_domains_finished) ? NULL : &proc_domains_op;
-}
 
-static void xeno_domains_stop(struct seq_file *s, void *v)
-{ 
-    up(&proc_xeno_domains_lock);
+    return ret;
 }
 
-static int xeno_domains_show(struct seq_file *s, void *v)
-{ 
-    dom0_op_t *di = v;
-  
-    /*
-     * Output one domain's details to dom0.
-     *
-     * If you update this format string then change xi_list to match.
-     */
-
-    seq_printf (s, 
-                "%8d %2d %1d %2d %8d %8ld %p %8d %s\n",
-                di -> u.getdominfo.domain, 
-                di -> u.getdominfo.processor,
-                di -> u.getdominfo.has_cpu,
-                di -> u.getdominfo.state,
-                di -> u.getdominfo.hyp_events,
-                di -> u.getdominfo.mcu_advance,
-                (void *)di -> u.getdominfo.pg_head,
-                di -> u.getdominfo.tot_pages,
-                di -> u.getdominfo.name);
-
-    return 0;
-}
 
-static struct seq_operations xeno_domains_op = {
-    .start          = xeno_domains_start,
-    .next           = xeno_domains_next,
-    .stop           = xeno_domains_stop,
-    .show           = xeno_domains_show,
+static struct file_operations privcmd_file_ops = {
+  ioctl : privcmd_ioctl
 };
 
-static int xeno_domains_open(struct inode *inode, struct file *file)
-{
-    return seq_open(file, &xeno_domains_op);
-}
-
-static struct file_operations proc_xeno_domains_operations = {
-    open:           xeno_domains_open,
-    read:           seq_read,
-    llseek:         seq_lseek,
-    release:        seq_release,
-};
-
-/***********************************************************************
- *
- * Implementation of /proc/xeno/dom0_cmd
- */
-
-static int dom0_cmd_write(struct file *file, const char *buffer, size_t size,
-                         loff_t *off)
-{
-    dom0_op_t op;
-    
-    copy_from_user(&op, buffer, sizeof(dom0_op_t));
-
-    return HYPERVISOR_dom0_op(&op);
-}
-
-static int handle_dom0_cmd_createdomain(unsigned long data)
-{
-  struct dom0_createdomain_args argbuf;
-  int namelen;
-  dom0_op_t op;
-  int ret;
-
-  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
-    return -EFAULT;
-
-  op.cmd = DOM0_CREATEDOMAIN;
-  op.u.newdomain.domain = -666;
-  op.u.newdomain.memory_kb = argbuf.kb_mem;
-  op.u.newdomain.num_vifs = 0; /* Not used anymore -- it's done in
-                                 BUILDDOMAIN. */
-  namelen = strnlen_user(argbuf.name, MAX_DOMAIN_NAME);
-  if (copy_from_user(op.u.newdomain.name, argbuf.name, namelen + 1))
-    return -EFAULT;
-
-  /* Error checking?  The old code deosn't appear to do any, and I
-     can't see where the return values are documented... */
-  ret = HYPERVISOR_dom0_op(&op);
-
-  if (op.u.newdomain.domain == -666) {
-    /* HACK: We use this to detect whether the create actually
-       succeeded, because Xen doesn't appear to want to tell us... */
-
-    /* The only time I've actually got this to happen was when trying
-       to create a domain with more memory than is actually in the
-       machine, so we guess the error code is ENOMEM. */
-    return -ENOMEM;
-  }
-
-  /* Create proc entries */
-  ret = op.u.newdomain.domain;
-  create_proc_dom_entries(ret);
-
-  return ret;
-}
-
-static unsigned long handle_dom0_cmd_mapdommem(unsigned long data)
-{
-  struct dom0_mapdommem_args argbuf;
-
-  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
-    return -EFAULT;
-
-  return direct_mmap(argbuf.start_pfn << PAGE_SHIFT,
-                    argbuf.tot_pages << PAGE_SHIFT,
-                    PAGE_SHARED,
-                    MAP_DISCONT,
-                    argbuf.tot_pages);
-}
-
-static int handle_dom0_cmd_unmapdommem(unsigned long data)
-{
-  struct dom0_unmapdommem_args argbuf;
-
-  if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
-    return -EFAULT;
-
-  return direct_unmap(current->mm, argbuf.vaddr,
-                     argbuf.tot_pages << PAGE_SHIFT);
-}
-
-static int handle_dom0_cmd_dopgupdates(unsigned long data)
-{
-    struct dom0_dopgupdates_args argbuf;
-    struct list_head *entry;
-    direct_mmap_node_t *node;
-
-    if (copy_from_user(&argbuf, (void *)data, sizeof(argbuf)))
-       return -EFAULT;
-
-    /* argbuf.pgt_update_arr had better be direct mapped... */
-    /* Actually, we only *really* need to make sure that all of it's
-       pages are in memory and aren't going to get swapped out in the
-       mean time, but this is slightly easier than checking all of
-       that and is sufficient for the current userspace tools. */
-    entry = find_direct(&current->mm->context.direct_list,
-                       argbuf.pgt_update_arr);
-    if (entry == &current->mm->context.direct_list)
-       return -EINVAL;
-    node = list_entry(entry, direct_mmap_node_t, list);
-    if (node->vm_start > argbuf.pgt_update_arr ||
-       node->vm_end <= argbuf.pgt_update_arr * sizeof(page_update_request_t))
-       return -EINVAL;
-    
-    return HYPERVISOR_pt_update((void *)argbuf.pgt_update_arr,
-                               argbuf.num_pgt_updates);
-}
-
-static int dom0_cmd_ioctl(struct inode *inode, struct file *file,
-                         unsigned int cmd, unsigned long data)
-{
-  switch (cmd) {
-  case IOCTL_DOM0_CREATEDOMAIN:
-    return handle_dom0_cmd_createdomain(data);
-  case IOCTL_DOM0_MAPDOMMEM:
-    return handle_dom0_cmd_mapdommem(data);
-  case IOCTL_DOM0_UNMAPDOMMEM:
-    return handle_dom0_cmd_unmapdommem(data);
-  case IOCTL_DOM0_DOPGUPDATES:
-    return handle_dom0_cmd_dopgupdates(data);
-  default:
-    return -ENOTTY; /* It isn't obvious why this is the correct error
-                      code when an ioctl isn't recognised, but it
-                      does appear to be what's used in the rest of
-                      the kernel. */
-  }
-}
-
-/***********************************************************************/
-
-
-static struct file_operations dom0_cmd_file_ops = {
-  write : dom0_cmd_write,
-  ioctl : dom0_cmd_ioctl
-};
 
 static int __init init_module(void)
 {
+    if ( !(start_info.flags & SIF_PRIVILEGED) )
+        return 0;
+
     /* xeno proc root setup */
     xeno_base = proc_mkdir("xeno", &proc_root); 
 
     /* xeno control interface */
-    dom0_cmd_intf = create_proc_entry("dom0_cmd", 0600, xeno_base);
-
-    if ( dom0_cmd_intf != NULL )
+    privcmd_intf = create_proc_entry("privcmd", 0400, xeno_base);
+    if ( privcmd_intf != NULL )
     {
-        dom0_cmd_intf->owner      = THIS_MODULE;
-        dom0_cmd_intf->nlink      = 1;
-       dom0_cmd_intf->proc_fops  = &dom0_cmd_file_ops;
+        privcmd_intf->owner      = THIS_MODULE;
+        privcmd_intf->nlink      = 1;
+       privcmd_intf->proc_fops  = &privcmd_file_ops;
     }
 
-    /* domain list interface */
-    dom_list_intf = create_proc_entry("domains", 0400, xeno_base);
-    if ( dom_list_intf != NULL )
-    {
-        dom_list_intf->owner = THIS_MODULE;
-        dom_list_intf->nlink = 1;
-        dom_list_intf->proc_fops = &proc_xeno_domains_operations;
-    }
-
-    /* set up /proc entries for dom 0 */
-    create_proc_dom_entries(0);
-
     return 0;
 }
 
 
 static void __exit cleanup_module(void)
 {
-    if ( dom0_cmd_intf == NULL ) return;
-    remove_proc_entry("dom0", &proc_root);
-    dom0_cmd_intf = NULL;
+    if ( privcmd_intf == NULL ) return;
+    remove_proc_entry("xeno", &proc_root);
+    privcmd_intf = NULL;
 }
 
 
diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_memory.c
deleted file mode 100644 (file)
index f36ac58..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/mman.h>
-#include <linux/swap.h>
-#include <linux/smp_lock.h>
-#include <linux/swapctl.h>
-#include <linux/iobuf.h>
-#include <linux/highmem.h>
-#include <linux/pagemap.h>
-#include <linux/list.h>
-
-#include <asm/pgalloc.h>
-#include <asm/uaccess.h>
-#include <asm/tlb.h>
-#include <asm/mmu.h>
-
-#include "dom0_ops.h"
-
-#define MAP_CONT    0
-#define MAP_DISCONT 1
-
-extern struct list_head * find_direct(struct list_head *, unsigned long);
-extern int direct_remap_area_pages(struct mm_struct *, unsigned long, 
-                                   unsigned long, unsigned long, pgprot_t);
-extern void direct_zap_page_range(struct mm_struct *, unsigned long, 
-                                  unsigned long);
-
-/* 
- * used for remapping discontiguous bits of domain's memory, pages to map are
- * found from frame table beginning at the given first_pg index
- */ 
-int direct_remap_disc_page_range(unsigned long from, 
-                                 unsigned long first_pg, 
-                                 int tot_pages, 
-                                 pgprot_t prot)
-{
-    dom0_op_t dom0_op;
-    unsigned long *pfns = (unsigned long *)get_free_page(GFP_KERNEL);
-    unsigned long start = from;
-    int pages, i;
-
-    while ( tot_pages != 0 )
-    {
-        dom0_op.cmd = DOM0_GETMEMLIST;
-        dom0_op.u.getmemlist.start_pfn = first_pg;
-        pages = 1023;
-        dom0_op.u.getmemlist.num_pfns = 1024;
-        if ( tot_pages < 1024 )
-            dom0_op.u.getmemlist.num_pfns = pages = tot_pages;
-        dom0_op.u.getmemlist.buffer = pfns;
-        (void)HYPERVISOR_dom0_op(&dom0_op);
-        first_pg = pfns[1023]; 
-
-        for ( i = 0; i < pages; i++ )
-        {
-            if(direct_remap_area_pages(current->mm,
-                                       start, pfns[i] << PAGE_SHIFT, 
-                                       PAGE_SIZE, prot))
-                goto out;
-            start += PAGE_SIZE;
-            tot_pages--;
-        }
-    }
-
- out:
-    free_page((unsigned long)pfns);
-    return tot_pages;
-} 
-           
-
-unsigned long direct_mmap(unsigned long phys_addr, unsigned long size, 
-                          pgprot_t prot, int flag, int tot_pages)
-{
-    direct_mmap_node_t * dmmap;
-    struct list_head * entry;
-    unsigned long addr;
-    int ret = 0;
-    
-    if(!capable(CAP_SYS_ADMIN)){
-        ret = -EPERM;
-        goto out;
-    }
-
-    /* get unmapped area invokes xen specific arch_get_unmapped_area */
-    addr = get_unmapped_area(NULL, 0, size, 0, 0);
-    if(addr & ~PAGE_MASK){
-        ret = -ENOMEM;
-        goto out;
-    }
-
-    /* add node on the list of directly mapped areas, make sure the
-     * list remains sorted.
-     */ 
-    dmmap = (direct_mmap_node_t *)kmalloc(sizeof(direct_mmap_node_t), GFP_KERNEL);
-    dmmap->vm_start = addr;
-    dmmap->vm_end = addr + size;
-    entry = find_direct(&current->mm->context.direct_list, addr);
-    if(entry != &current->mm->context.direct_list){
-        list_add_tail(&dmmap->list, entry);
-    } else {
-       list_add_tail(&dmmap->list, &current->mm->context.direct_list);
-    }
-
-    /* and perform the mapping */
-    if(flag == MAP_DISCONT){
-        ret = direct_remap_disc_page_range(addr, phys_addr >> PAGE_SHIFT, 
-                                           tot_pages, prot);
-    } else {
-        ret = direct_remap_area_pages(current->mm, 
-                                      addr, phys_addr, size, prot);
-    }
-
-    if(ret == 0)
-        ret = addr;
-
- out: 
-    return ret;
-}
-
-
-int direct_unmap(struct mm_struct *mm, unsigned long addr, unsigned long size)
-{
-    int count = 0, tot_pages = (size+PAGE_SIZE-1) >> PAGE_SHIFT;
-    direct_mmap_node_t * node;
-    struct list_head * curr;
-    struct list_head * direct_list = &mm->context.direct_list;    
-
-    curr = direct_list->next;
-    while ( curr != direct_list )
-    {
-        node = list_entry(curr, direct_mmap_node_t, list);
-        if ( node->vm_start == addr )
-            break;
-        curr = curr->next;
-    }
-
-    if ( curr == direct_list )
-        return -1;
-
-    list_del(&node->list);
-    kfree(node);
-
-    while ( count < tot_pages )
-    {
-        direct_zap_page_range(mm, addr, PAGE_SIZE);
-        addr += PAGE_SIZE;
-        count++;
-    }
-
-    return 0;
-} 
diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/dom0_ops.h
deleted file mode 100644 (file)
index 23006ea..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/******************************************************************************
- * dom0_ops.h
- * 
- * Process command requests from domain-0 guest OS.
- * This file includes the Xen part of the interface, plus the extra stuff
- * that is dealt with by Xenolinux without being handed down to Xen.
- * 
- * Copyright (c) 2002-2003, K A Fraser, B Dragovic
- */
-
-#ifndef __DOM0_DOM0_OPS_H__
-#define __DOM0_DOM0_OPS_H__
-
-/* External users of this header file will include Xen's version separately. */
-#ifdef __KERNEL__
-#define NO_DOM0_OP_T
-#include <asm/hypervisor-ifs/dom0_ops.h>
-#endif
-
-/* Extra commands dealt with by Xenolinux. */
-#define MAP_DOM_MEM        1014
-#define DO_PGUPDATES       1015
-
-typedef struct dom_mem 
-{
-    unsigned int domain;
-    unsigned long vaddr;
-    unsigned long start_pfn;
-    int tot_pages;
-} dom_mem_t;
-
-typedef struct dom_pgupdate
-{
-    unsigned long pgt_update_arr;
-    unsigned long num_pgt_updates;
-} dom_pgupdate_t;
-
-typedef struct dom0_op_st
-{
-    unsigned long cmd;
-    union
-    {
-        dom0_newdomain_t newdomain;
-        dom0_killdomain_t killdomain;
-        dom0_getmemlist_t getmemlist;
-        dom0_bvtctl_t bvtctl;
-        dom0_adjustdom_t adjustdom;
-        dom_mem_t dommem;
-        dom_pgupdate_t pgupdate;
-        dom_meminfo_t meminfo;
-        dom0_getdominfo_t getdominfo;
-        dom0_iopl_t iopl;
-   } u;
-} dom0_op_t;
-
-#endif /* __DOM0_DOM0_OPS_H__ */
diff --git a/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c b/xenolinux-2.4.21-sparse/arch/xeno/drivers/dom0/sched_ops.c
deleted file mode 100644 (file)
index 9c5fce7..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-/* -*-  Mode:C; c-basic-offset:4; tab-width:4 -*-
- ****************************************************************************
- * (C) 2003 - Rolf Neugebauer - Intel Research Cambridge
- ****************************************************************************
- *
- *        File: sched_ops.c
- *      Author: Rolf Neugebauer (neugebar@dcs.gla.ac.uk)
- *     Changes: 
- *              
- *        Date: Mar 2003
- * 
- * Environment: XenoLinux
- * Description: Dom0 Control interface to scheduler in Xen
- *
- * code based on Andy's vfr parsing code
- *
- * Commands understood by the interface:
- *
- * C <context swith allowance>
- * S <did> <mcu advance> <warp> <warp limit> <unwarp limit>
- *
- ****************************************************************************
- * $Id: c-insert.c,v 1.7 2002/11/08 16:04:34 rn Exp $
- ****************************************************************************
- */
-
-#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/ctype.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/proc_fs.h>
-
-#include "dom0_ops.h"
-
-#define SCHED_ENTRY    "sched"
-extern struct proc_dir_entry *xeno_base;
-static struct proc_dir_entry *sched_pde;
-
-static unsigned char readbuf[1024];
-
-static int sched_read_proc(char *page, char **start, off_t off,
-                           int count, int *eof, void *data)
-{   
-    strcpy(page, readbuf);
-    *readbuf = '\0';
-    *eof = 1;
-    *start = page;
-    return strlen(page);
-}
-
-
-static int sched_write_proc(struct file *file, const char *buffer,
-                            u_long count, void *data)
-{
-    dom0_op_t op;
-
-    int ret, len;
-    int ts, te, tl; /* token start, end, and length */
-
-    /* Only admin can adjust scheduling parameters */
-    if ( !capable(CAP_SYS_ADMIN) )
-        return -EPERM;
-
-    /* parse the commands  */
-    len = count;
-    ts = te = 0;
-
-    while ( count && isspace(buffer[ts]) ) { ts++; count--; } /*skip spaces*/
-    te = ts;
-    while ( count && !isspace(buffer[te]) ) { te++; count--; } /*command end*/
-    if ( te <= ts ) goto bad;
-    tl = te - ts;
-
-    if ( strncmp(&buffer[ts], "C", tl) == 0 ) {
-        op.cmd = DOM0_BVTCTL;
-    } else if ( strncmp(&buffer[ts], "S", tl) == 0 ) {
-        op.cmd = DOM0_ADJUSTDOM;
-    } else
-        goto bad;
-
-    /* skip whitspaces and get first parameter */
-    ts = te; while ( count &&  isspace(buffer[ts]) ) { ts++; count--; }
-    te = ts; while ( count && !isspace(buffer[te]) ) { te++; count--; }
-    if ( te <= ts ) goto bad;
-    tl = te - ts;
-    if ( !isdigit(buffer[ts]) ) goto bad;
-
-    if (op.cmd == DOM0_BVTCTL) {
-        /* get context switch allowance  */
-        sscanf(&buffer[ts], "%lu", &op.u.bvtctl.ctx_allow);
-    } else if (op.cmd == DOM0_ADJUSTDOM) {
-        sscanf(&buffer[ts], "%u %lu %lu %lu %lu",
-               &op.u.adjustdom.domain,
-               &op.u.adjustdom.mcu_adv,
-               &op.u.adjustdom.warp,
-               &op.u.adjustdom.warpl,
-               &op.u.adjustdom.warpu);
-    }
-    ret = HYPERVISOR_dom0_op(&op);
-    return sizeof(op);
-    
- bad:
-    return -EINVAL;
-
-}
-
-
-/*
- * main scheduler interface driver driver initialization function.
- */
-static int __init init_module(void)
-{
-    printk(KERN_ALERT "Starting Domain Scheduler Control Interface\n");
-
-    sched_pde = create_proc_entry(SCHED_ENTRY, 0600, xeno_base);
-    if ( sched_pde == NULL )
-    {
-        printk(KERN_ALERT "Unable to create dom scheduler proc entry!");
-        return -1;
-    }
-
-    sched_pde->read_proc  = sched_read_proc;
-    sched_pde->write_proc = sched_write_proc;
-
-    return 0;
-}
-
-static void __exit cleanup_module(void)
-{
-}
-
-module_init(init_module);
-module_exit(cleanup_module);
-
index 852f6943e24138f2b8e9d76cd1714033a78c57f3..2091464169798f183d12b418fe638ff54b621dd7 100644 (file)
@@ -224,7 +224,7 @@ static int vfr_write_proc(struct file *file, const char *buffer,
 static int __init init_module(void)
 {
     *readbuf = '\0';
-    proc_vfr = create_proc_entry ("vfr", 0600, &proc_root);
+    proc_vfr = create_proc_entry ("xeno/vfr", 0600, &proc_root);
     if ( proc_vfr != NULL )
     {
         proc_vfr->owner      = THIS_MODULE;
@@ -239,7 +239,7 @@ static int __init init_module(void)
 static void __exit cleanup_module(void)
 {
     if ( proc_vfr == NULL ) return;
-    remove_proc_entry("vfr", &proc_root);
+    remove_proc_entry("xeno/vfr", &proc_root);
     proc_vfr = NULL;
 }
 
index 6798d5259ff2c3cadd47b7582144d67cf62c8784..3b17c7326c692c376e41fb034517441451ad5404 100644 (file)
@@ -145,9 +145,6 @@ void release_segments(struct mm_struct *mm)
         flush_page_update_queue();
         vfree(ldt);
     }
-
-    /* YUK! We do this here because destroy_context() is too late. */
-    destroy_direct_list(mm);
 }
 
 /*
index 79c93767fdcecb45a9fd870aade764c1c5f4eeb5..d0d16114b631d5183ea38d63347509621f418148 100644 (file)
@@ -9,7 +9,7 @@
 
 O_TARGET := mm.o
 
-obj-y   := init.o fault.o extable.o pageattr.o hypervisor.o get_unmapped_area.o ioremap.o
+obj-y   := init.o fault.o extable.o pageattr.o hypervisor.o ioremap.o
 
 export-objs := pageattr.o
 
diff --git a/xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c b/xenolinux-2.4.21-sparse/arch/xeno/mm/get_unmapped_area.c
deleted file mode 100644 (file)
index 2258d01..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-
-#include <linux/slab.h>
-#include <linux/shm.h>
-#include <linux/mman.h>
-#include <linux/pagemap.h>
-#include <linux/swap.h>
-#include <linux/swapctl.h>
-#include <linux/smp_lock.h>
-#include <linux/init.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/personality.h>
-
-#include <asm/uaccess.h>
-#include <asm/pgalloc.h>
-
-extern int direct_unmap(struct mm_struct *, unsigned long, unsigned long);
-
-int init_direct_list(struct mm_struct *mm)
-{
-    INIT_LIST_HEAD(&mm->context.direct_list);
-    return 0;
-}
-
-
-void destroy_direct_list(struct mm_struct *mm)
-{
-    struct list_head *curr, *direct_list = &mm->context.direct_list;
-    while ( (curr = direct_list->next) != direct_list )
-    {
-        direct_mmap_node_t *node = list_entry(curr, direct_mmap_node_t, list);
-        if ( direct_unmap(mm, node->vm_start, node->vm_end - node->vm_start) )
-            BUG();
-    }
-}
-
-
-struct list_head *find_direct(struct list_head *list, unsigned long addr)
-{
-    struct list_head * curr;
-    struct list_head * direct_list = &current->mm->context.direct_list;
-    direct_mmap_node_t * node;
-
-    for ( curr = direct_list->next; curr != direct_list; curr = curr->next )
-    {
-        node = list_entry(curr, direct_mmap_node_t, list);
-        if ( node->vm_start >= addr ) break;
-    }
-
-    return curr;
-}
-
-
-unsigned long arch_get_unmapped_area(struct file *filp, 
-                                     unsigned long addr, 
-                                     unsigned long len, 
-                                     unsigned long pgoff, 
-                                     unsigned long flags)
-{
-    struct vm_area_struct *vma;
-    direct_mmap_node_t * node;
-    struct list_head * curr;
-    struct list_head * direct_list = &current->mm->context.direct_list;
-
-    if ( len > TASK_SIZE )
-        return -ENOMEM;
-
-    if ( addr )
-    {
-        addr = PAGE_ALIGN(addr);
-        vma = find_vma(current->mm, addr);
-        curr = find_direct(direct_list, addr);
-        node = list_entry(curr, direct_mmap_node_t, list);
-        if ( (TASK_SIZE - len >= addr) &&
-             (!vma || addr + len <= vma->vm_start) &&
-             ((curr == direct_list) || addr + len <= node->vm_start) )
-            return addr;
-    }
-
-    addr = PAGE_ALIGN(TASK_UNMAPPED_BASE);
-
-
-    /* Find first VMA and direct_map nodes with vm_start > addr */
-    vma  = find_vma(current->mm, addr);
-    curr = find_direct(direct_list, addr);
-    node = list_entry(curr, direct_mmap_node_t, list);
-
-    for ( ; ; )
-    {
-        if ( TASK_SIZE - len < addr ) return -ENOMEM;
-
-        if ( vma && ((curr == direct_list) || 
-                     (vma->vm_start < node->vm_start)) )
-        {
-            /* Do we fit before VMA node? */
-            if ( addr + len <= vma->vm_start ) return addr;
-            addr = vma->vm_end;
-            vma = vma->vm_next;
-        }
-        else if ( curr != direct_list )
-        {
-            /* Do we fit before direct_map node? */
-            if ( addr + len <= node->vm_start) return addr;
-            addr = node->vm_end;
-            curr = curr->next;
-            node = list_entry(curr, direct_mmap_node_t, list);
-        }
-        else
-        {
-            /* !vma && curr == direct_list */
-            return addr;
-        }
-    }
-}
index f7c6fad27828f276c0eec74d72bd3ea1001a948e..db0221d2dda975a5a68da7455d428dd6dc6d23c6 100644 (file)
 #include <asm/tlb.h>
 #include <asm/mmu.h>
 
+#if defined(CONFIG_XENO_PRIV)
+
 #define direct_set_pte(pteptr, pteval) \
   queue_l1_entry_update(__pa(pteptr)|PGREQ_UNCHECKED_UPDATE, (pteval).pte_low)
-#define direct_pte_clear(pteptr) \
-  queue_l1_entry_update(__pa(pteptr)|PGREQ_UNCHECKED_UPDATE, 0)
 #define __direct_pte(x) ((pte_t) { (x) } )
 #define __direct_mk_pte(page_nr,pgprot) \
   __direct_pte(((page_nr) << PAGE_SHIFT) | pgprot_val(pgprot))
@@ -29,9 +29,6 @@
   __direct_mk_pte((physpage) >> PAGE_SHIFT, pgprot)
 
 
-
-/******************* Mapping a page range directly ************************/
-
 static inline void direct_remap_area_pte(pte_t *pte, 
                                          unsigned long address, 
                                          unsigned long size,
@@ -51,7 +48,7 @@ static inline void direct_remap_area_pte(pte_t *pte,
             printk("direct_remap_area_pte: page already exists\n");
             BUG();
         }
-        direct_set_pte(pte, direct_mk_pte_phys(machine_addr, prot)); 
+        direct_set_pte(pte, pte_mkio(direct_mk_pte_phys(machine_addr, prot))); 
         address += PAGE_SIZE;
         machine_addr += PAGE_SIZE;
         pte++;
@@ -119,105 +116,9 @@ int direct_remap_area_pages(struct mm_struct *mm,
     return error;
 }
 
+#endif /* CONFIG_XENO_PRIV */
 
 
-/************************ Zapping a page range directly *******************/
-
-static inline int direct_zap_pte_range(mmu_gather_t *tlb, 
-                                       pmd_t * pmd, 
-                                       unsigned long address, 
-                                       unsigned long size)
-{
-    unsigned long offset;
-    pte_t * ptep;
-    int freed = 0;
-
-    if (pmd_none(*pmd))
-        return 0;
-    if (pmd_bad(*pmd)) {
-        pmd_ERROR(*pmd);
-        pmd_clear(pmd);
-        return 0;
-    }
-    ptep = pte_offset(pmd, address);
-    offset = address & ~PMD_MASK;
-    if (offset + size > PMD_SIZE)
-        size = PMD_SIZE - offset;
-    size &= PAGE_MASK;
-    for (offset=0; offset < size; ptep++, offset += PAGE_SIZE) {
-        pte_t pte = *ptep;
-        if (pte_none(pte))
-            continue;
-        freed++;
-        direct_pte_clear(ptep);
-    }
-
-    return freed;
-}
-
-static inline int direct_zap_pmd_range(mmu_gather_t *tlb, 
-                                       pgd_t * dir, 
-                                       unsigned long address, 
-                                       unsigned long size)
-{
-    pmd_t * pmd;
-    unsigned long end;
-    int freed;
-
-    if (pgd_none(*dir))
-        return 0;
-    if (pgd_bad(*dir)) {
-        pgd_ERROR(*dir);
-        pgd_clear(dir);
-        return 0;
-    }
-    pmd = pmd_offset(dir, address);
-    end = address + size;
-    if (end > ((address + PGDIR_SIZE) & PGDIR_MASK))
-        end = ((address + PGDIR_SIZE) & PGDIR_MASK);
-    freed = 0;
-    do {
-        freed += direct_zap_pte_range(tlb, pmd, address, end - address);
-        address = (address + PMD_SIZE) & PMD_MASK; 
-        pmd++;
-    } while (address < end);
-    return freed;
-}
-
-void direct_zap_page_range(struct mm_struct *mm, 
-                           unsigned long address, 
-                           unsigned long size)
-{
-    mmu_gather_t *tlb;
-    pgd_t * dir;
-    unsigned long start = address, end = address + size;
-    int freed = 0;
-
-    dir = pgd_offset(mm, address);
-
-    if (address >= end)
-        BUG();
-    spin_lock(&mm->page_table_lock);
-    flush_cache_range(mm, address, end);
-    tlb = tlb_gather_mmu(mm);
-
-    do {
-        freed += direct_zap_pmd_range(tlb, dir, address, end - address);
-        address = (address + PGDIR_SIZE) & PGDIR_MASK;
-        dir++;
-    } while (address && (address < end));
-
-    /* this will flush any remaining tlb entries */
-    tlb_finish_mmu(tlb, start, end);
-
-    /* decrementing rss removed */
-    spin_unlock(&mm->page_table_lock);
-}
-
-
-
-/****************** Generic public functions ****************************/
-
 /*
  * Remap an arbitrary machine address space into the kernel virtual
  * address space. Needed when a privileged instance of Xenolinux wants
@@ -231,6 +132,7 @@ void * __ioremap(unsigned long machine_addr,
                  unsigned long size, 
                  unsigned long flags)
 {
+#if defined(CONFIG_XENO_PRIV)
     void * addr;
     struct vm_struct * area;
     unsigned long offset, last_addr;
@@ -255,45 +157,22 @@ void * __ioremap(unsigned long machine_addr,
     if (!area)
         return NULL;
     addr = area->addr;
-    prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | 
-                    flags);
+    prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | 
+                    _PAGE_ACCESSED | flags);
     if (direct_remap_area_pages(&init_mm, VMALLOC_VMADDR(addr), 
                                 machine_addr, size, prot)) {
         vfree(addr);
         return NULL;
     }
     return (void *) (offset + (char *)addr);
+#else
+    return NULL;
+#endif
 }
 
-/*
- * 'vfree' is basically inlined here. This is because we use a different
- * function to zap the associated page range.
- */
 void iounmap(void *addr)
 {
-    struct vm_struct **p, *tmp;
-
-    addr = (void *)((unsigned long)addr & PAGE_MASK);
-    
-    if (addr == NULL)
-        return;
-
-    write_lock(&vmlist_lock);
-
-    for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
-        if (tmp->addr == addr) {
-            *p = tmp->next;
-            direct_zap_page_range(&init_mm, 
-                                  VMALLOC_VMADDR(tmp->addr), 
-                                  tmp->size);
-            write_unlock(&vmlist_lock);
-            kfree(tmp);
-            return;
-        }
-    }
-
-    write_unlock(&vmlist_lock);
-    printk(KERN_ERR "Trying to iounmap() nonexistent vm area (%p)\n", addr);
+    vfree((void *)((unsigned long)addr & PAGE_MASK));
 }
 
 
diff --git a/xenolinux-2.4.21-sparse/drivers/char/mem.c b/xenolinux-2.4.21-sparse/drivers/char/mem.c
new file mode 100644 (file)
index 0000000..bb0ab61
--- /dev/null
@@ -0,0 +1,807 @@
+/*
+ *  linux/drivers/char/mem.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Added devfs support. 
+ *    Jan-11-1998, C. Scott Ananian <cananian@alumni.princeton.edu>
+ *  Shared /dev/zero mmaping support, Feb 2000, Kanoj Sarcar <kanoj@sgi.com>
+ *
+ *  MODIFIED FOR XENOLINUX by Keir Fraser, 10th July 2003.
+ *  Xenolinux has strange semantics for /dev/mem and /dev/kmem!!
+ *   1. mmap will not work on /dev/kmem
+ *   2. mmap on /dev/mem interprets the 'file offset' as a machine address
+ *      rather than a physical address.
+ *  I don't believe anyone sane mmaps /dev/kmem, but /dev/mem is mmapped
+ *  to get at memory-mapped I/O spaces (eg. the VESA X server does this).
+ *  For this to work at all we need to expect machine addresses.
+ *  Reading/writing of /dev/kmem expects kernel virtual addresses, as usual.
+ *  Reading/writing of /dev/mem expects 'physical addresses' as usual -- this
+ *  is because /dev/mem can only read/write existing kernel mappings, which
+ *  will be normal RAM, and we should present pseudo-physical layout for all
+ *  except I/O (which is the sticky case that mmap is hacked to deal with).
+ */
+
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/miscdevice.h>
+#include <linux/tpqic02.h>
+#include <linux/ftape.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mman.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/raw.h>
+#include <linux/tty.h>
+#include <linux/capability.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/pgalloc.h>
+
+#ifdef CONFIG_I2C
+extern int i2c_init_all(void);
+#endif
+#ifdef CONFIG_FB
+extern void fbmem_init(void);
+#endif
+#ifdef CONFIG_PROM_CONSOLE
+extern void prom_con_init(void);
+#endif
+#ifdef CONFIG_MDA_CONSOLE
+extern void mda_console_init(void);
+#endif
+#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
+extern void tapechar_init(void);
+#endif
+     
+static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp,
+                           const char * buf, size_t count, loff_t *ppos)
+{
+       ssize_t written;
+
+       written = 0;
+#if defined(__sparc__) || defined(__mc68000__)
+       /* we don't have page 0 mapped on sparc and m68k.. */
+       if (realp < PAGE_SIZE) {
+               unsigned long sz = PAGE_SIZE-realp;
+               if (sz > count) sz = count; 
+               /* Hmm. Do something? */
+               buf+=sz;
+               p+=sz;
+               count-=sz;
+               written+=sz;
+       }
+#endif
+       if (copy_from_user(p, buf, count))
+               return -EFAULT;
+       written += count;
+       *ppos += written;
+       return written;
+}
+
+
+/*
+ * This funcion reads the *physical* memory. The f_pos points directly to the 
+ * memory location. 
+ */
+static ssize_t read_mem(struct file * file, char * buf,
+                       size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       unsigned long end_mem;
+       ssize_t read;
+       
+       end_mem = __pa(high_memory);
+       if (p >= end_mem)
+               return 0;
+       if (count > end_mem - p)
+               count = end_mem - p;
+       read = 0;
+#if defined(__sparc__) || defined(__mc68000__)
+       /* we don't have page 0 mapped on sparc and m68k.. */
+       if (p < PAGE_SIZE) {
+               unsigned long sz = PAGE_SIZE-p;
+               if (sz > count) 
+                       sz = count; 
+               if (sz > 0) {
+                       if (clear_user(buf, sz))
+                               return -EFAULT;
+                       buf += sz; 
+                       p += sz; 
+                       count -= sz; 
+                       read += sz; 
+               }
+       }
+#endif
+       if (copy_to_user(buf, __va(p), count))
+               return -EFAULT;
+       read += count;
+       *ppos += read;
+       return read;
+}
+
+static ssize_t write_mem(struct file * file, const char * buf, 
+                        size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       unsigned long end_mem;
+
+       end_mem = __pa(high_memory);
+       if (p >= end_mem)
+               return 0;
+       if (count > end_mem - p)
+               count = end_mem - p;
+       return do_write_mem(file, __va(p), p, buf, count, ppos);
+}
+
+#ifndef pgprot_noncached
+
+/*
+ * This should probably be per-architecture in <asm/pgtable.h>
+ */
+static inline pgprot_t pgprot_noncached(pgprot_t _prot)
+{
+       unsigned long prot = pgprot_val(_prot);
+
+#if defined(__i386__) || defined(__x86_64__)
+       /* On PPro and successors, PCD alone doesn't always mean 
+           uncached because of interactions with the MTRRs. PCD | PWT
+           means definitely uncached. */ 
+       if (boot_cpu_data.x86 > 3)
+               prot |= _PAGE_PCD | _PAGE_PWT;
+#elif defined(__powerpc__)
+       prot |= _PAGE_NO_CACHE | _PAGE_GUARDED;
+#elif defined(__mc68000__)
+#ifdef SUN3_PAGE_NOCACHE
+       if (MMU_IS_SUN3)
+               prot |= SUN3_PAGE_NOCACHE;
+       else
+#endif
+       if (MMU_IS_851 || MMU_IS_030)
+               prot |= _PAGE_NOCACHE030;
+       /* Use no-cache mode, serialized */
+       else if (MMU_IS_040 || MMU_IS_060)
+               prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S;
+#endif
+
+       return __pgprot(prot);
+}
+
+#endif /* !pgprot_noncached */
+
+/*
+ * Architectures vary in how they handle caching for addresses 
+ * outside of main memory.
+ */
+static inline int noncached_address(unsigned long addr)
+{
+#if defined(__i386__)
+       /* 
+        * On the PPro and successors, the MTRRs are used to set
+        * memory types for physical addresses outside main memory, 
+        * so blindly setting PCD or PWT on those pages is wrong.
+        * For Pentiums and earlier, the surround logic should disable 
+        * caching for the high addresses through the KEN pin, but
+        * we maintain the tradition of paranoia in this code.
+        */
+       return !( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ||
+                 test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ||
+                 test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ||
+                 test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) )
+         && addr >= __pa(high_memory);
+#else
+       return addr >= __pa(high_memory);
+#endif
+}
+
+static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+{
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+
+#if defined(CONFIG_XENO) && defined(CONFIG_XENO_PRIV)
+       if (!(start_info.flags & SIF_PRIVILEGED))
+               return -ENXIO;
+
+       /* DONTCOPY is essential for Xenolinux as copy_page_range is broken. */
+       vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY;
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+       if (direct_remap_area_pages(vma->vm_mm, vma->vm_start, offset, 
+                            vma->vm_end-vma->vm_start, vma->vm_page_prot))
+               return -EAGAIN;
+       return 0;
+#elif defined(CONFIG_XENO)
+       return -ENXIO;
+#else
+       /*
+        * Accessing memory above the top the kernel knows about or
+        * through a file pointer that was marked O_SYNC will be
+        * done non-cached.
+        */
+       if (noncached_address(offset) || (file->f_flags & O_SYNC))
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       /* Don't try to swap out physical pages.. */
+       vma->vm_flags |= VM_RESERVED;
+
+       /*
+        * Don't dump addresses that are not real memory to a core file.
+        */
+       if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC))
+               vma->vm_flags |= VM_IO;
+
+       if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start,
+                            vma->vm_page_prot))
+               return -EAGAIN;
+       return 0;
+#endif
+}
+
+/*
+ * This function reads the *virtual* memory as seen by the kernel.
+ */
+static ssize_t read_kmem(struct file *file, char *buf, 
+                        size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       ssize_t read = 0;
+       ssize_t virtr = 0;
+       char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
+               
+       if (p < (unsigned long) high_memory) {
+               read = count;
+               if (count > (unsigned long) high_memory - p)
+                       read = (unsigned long) high_memory - p;
+
+#if defined(__sparc__) || defined(__mc68000__)
+               /* we don't have page 0 mapped on sparc and m68k.. */
+               if (p < PAGE_SIZE && read > 0) {
+                       size_t tmp = PAGE_SIZE - p;
+                       if (tmp > read) tmp = read;
+                       if (clear_user(buf, tmp))
+                               return -EFAULT;
+                       buf += tmp;
+                       p += tmp;
+                       read -= tmp;
+                       count -= tmp;
+               }
+#endif
+               if (copy_to_user(buf, (char *)p, read))
+                       return -EFAULT;
+               p += read;
+               buf += read;
+               count -= read;
+       }
+
+       if (count > 0) {
+               kbuf = (char *)__get_free_page(GFP_KERNEL);
+               if (!kbuf)
+                       return -ENOMEM;
+               while (count > 0) {
+                       int len = count;
+
+                       if (len > PAGE_SIZE)
+                               len = PAGE_SIZE;
+                       len = vread(kbuf, (char *)p, len);
+                       if (!len)
+                               break;
+                       if (copy_to_user(buf, kbuf, len)) {
+                               free_page((unsigned long)kbuf);
+                               return -EFAULT;
+                       }
+                       count -= len;
+                       buf += len;
+                       virtr += len;
+                       p += len;
+               }
+               free_page((unsigned long)kbuf);
+       }
+       *ppos = p;
+       return virtr + read;
+}
+
+extern long vwrite(char *buf, char *addr, unsigned long count);
+
+/*
+ * This function writes to the *virtual* memory as seen by the kernel.
+ */
+static ssize_t write_kmem(struct file * file, const char * buf, 
+                         size_t count, loff_t *ppos)
+{
+       unsigned long p = *ppos;
+       ssize_t wrote = 0;
+       ssize_t virtr = 0;
+       char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
+
+       if (p < (unsigned long) high_memory) {
+               wrote = count;
+               if (count > (unsigned long) high_memory - p)
+                       wrote = (unsigned long) high_memory - p;
+
+               wrote = do_write_mem(file, (void*)p, p, buf, wrote, ppos);
+
+               p += wrote;
+               buf += wrote;
+               count -= wrote;
+       }
+
+       if (count > 0) {
+               kbuf = (char *)__get_free_page(GFP_KERNEL);
+               if (!kbuf)
+                       return -ENOMEM;
+               while (count > 0) {
+                       int len = count;
+
+                       if (len > PAGE_SIZE)
+                               len = PAGE_SIZE;
+                       if (len && copy_from_user(kbuf, buf, len)) {
+                               free_page((unsigned long)kbuf);
+                               return -EFAULT;
+                       }
+                       len = vwrite(kbuf, (char *)p, len);
+                       count -= len;
+                       buf += len;
+                       virtr += len;
+                       p += len;
+               }
+               free_page((unsigned long)kbuf);
+       }
+
+       *ppos = p;
+       return virtr + wrote;
+}
+
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
+static ssize_t read_port(struct file * file, char * buf,
+                        size_t count, loff_t *ppos)
+{
+       unsigned long i = *ppos;
+       char *tmp = buf;
+
+       if (verify_area(VERIFY_WRITE,buf,count))
+               return -EFAULT; 
+       while (count-- > 0 && i < 65536) {
+               if (__put_user(inb(i),tmp) < 0) 
+                       return -EFAULT;  
+               i++;
+               tmp++;
+       }
+       *ppos = i;
+       return tmp-buf;
+}
+
+static ssize_t write_port(struct file * file, const char * buf,
+                         size_t count, loff_t *ppos)
+{
+       unsigned long i = *ppos;
+       const char * tmp = buf;
+
+       if (verify_area(VERIFY_READ,buf,count))
+               return -EFAULT;
+       while (count-- > 0 && i < 65536) {
+               char c;
+               if (__get_user(c, tmp)) 
+                       return -EFAULT; 
+               outb(c,i);
+               i++;
+               tmp++;
+       }
+       *ppos = i;
+       return tmp-buf;
+}
+#endif
+
+static ssize_t read_null(struct file * file, char * buf,
+                        size_t count, loff_t *ppos)
+{
+       return 0;
+}
+
+static ssize_t write_null(struct file * file, const char * buf,
+                         size_t count, loff_t *ppos)
+{
+       return count;
+}
+
+/*
+ * For fun, we are using the MMU for this.
+ */
+static inline size_t read_zero_pagealigned(char * buf, size_t size)
+{
+       struct mm_struct *mm;
+       struct vm_area_struct * vma;
+       unsigned long addr=(unsigned long)buf;
+
+       mm = current->mm;
+       /* Oops, this was forgotten before. -ben */
+       down_read(&mm->mmap_sem);
+
+       /* For private mappings, just map in zero pages. */
+       for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
+               unsigned long count;
+
+               if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
+                       goto out_up;
+               if (vma->vm_flags & VM_SHARED)
+                       break;
+#if defined(CONFIG_XENO_PRIV)
+               if (vma->vm_flags & VM_IO)
+                       break;
+#endif
+               count = vma->vm_end - addr;
+               if (count > size)
+                       count = size;
+
+               zap_page_range(mm, addr, count);
+               zeromap_page_range(addr, count, PAGE_COPY);
+
+               size -= count;
+               buf += count;
+               addr += count;
+               if (size == 0)
+                       goto out_up;
+       }
+
+       up_read(&mm->mmap_sem);
+       
+       /* The shared case is hard. Let's do the conventional zeroing. */ 
+       do {
+               unsigned long unwritten = clear_user(buf, PAGE_SIZE);
+               if (unwritten)
+                       return size + unwritten - PAGE_SIZE;
+               if (current->need_resched)
+                       schedule();
+               buf += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       } while (size);
+
+       return size;
+out_up:
+       up_read(&mm->mmap_sem);
+       return size;
+}
+
+static ssize_t read_zero(struct file * file, char * buf, 
+                        size_t count, loff_t *ppos)
+{
+       unsigned long left, unwritten, written = 0;
+
+       if (!count)
+               return 0;
+
+       if (!access_ok(VERIFY_WRITE, buf, count))
+               return -EFAULT;
+
+       left = count;
+
+       /* do we want to be clever? Arbitrary cut-off */
+       if (count >= PAGE_SIZE*4) {
+               unsigned long partial;
+
+               /* How much left of the page? */
+               partial = (PAGE_SIZE-1) & -(unsigned long) buf;
+               unwritten = clear_user(buf, partial);
+               written = partial - unwritten;
+               if (unwritten)
+                       goto out;
+               left -= partial;
+               buf += partial;
+               unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
+               written += (left & PAGE_MASK) - unwritten;
+               if (unwritten)
+                       goto out;
+               buf += left & PAGE_MASK;
+               left &= ~PAGE_MASK;
+       }
+       unwritten = clear_user(buf, left);
+       written += left - unwritten;
+out:
+       return written ? written : -EFAULT;
+}
+
+static int mmap_zero(struct file * file, struct vm_area_struct * vma)
+{
+       if (vma->vm_flags & VM_SHARED)
+               return shmem_zero_setup(vma);
+       if (zeromap_page_range(vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot))
+               return -EAGAIN;
+       return 0;
+}
+
+static ssize_t write_full(struct file * file, const char * buf,
+                         size_t count, loff_t *ppos)
+{
+       return -ENOSPC;
+}
+
+/*
+ * Special lseek() function for /dev/null and /dev/zero.  Most notably, you
+ * can fopen() both devices with "a" now.  This was previously impossible.
+ * -- SRB.
+ */
+
+static loff_t null_lseek(struct file * file, loff_t offset, int orig)
+{
+       return file->f_pos = 0;
+}
+
+/*
+ * The memory devices use the full 32/64 bits of the offset, and so we cannot
+ * check against negative addresses: they are ok. The return value is weird,
+ * though, in that case (0).
+ *
+ * also note that seeking relative to the "end of file" isn't supported:
+ * it has no meaning, so it returns -EINVAL.
+ */
+static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
+{
+       switch (orig) {
+               case 0:
+                       file->f_pos = offset;
+                       return file->f_pos;
+               case 1:
+                       file->f_pos += offset;
+                       return file->f_pos;
+               default:
+                       return -EINVAL;
+       }
+}
+
+static int open_port(struct inode * inode, struct file * filp)
+{
+       return capable(CAP_SYS_RAWIO) ? 0 : -EPERM;
+}
+
+struct page *kmem_vm_nopage(struct vm_area_struct *vma, unsigned long address, int write)
+{
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long kaddr;
+       pgd_t *pgd;
+       pmd_t *pmd;
+       pte_t *ptep, pte;
+       struct page *page = NULL;
+
+       /* address is user VA; convert to kernel VA of desired page */
+       kaddr = (address - vma->vm_start) + offset;
+       kaddr = VMALLOC_VMADDR(kaddr);
+
+       spin_lock(&init_mm.page_table_lock);
+
+       /* Lookup page structure for kernel VA */
+       pgd = pgd_offset(&init_mm, kaddr);
+       if (pgd_none(*pgd) || pgd_bad(*pgd))
+               goto out;
+       pmd = pmd_offset(pgd, kaddr);
+       if (pmd_none(*pmd) || pmd_bad(*pmd))
+               goto out;
+       ptep = pte_offset(pmd, kaddr);
+       if (!ptep)
+               goto out;
+       pte = *ptep;
+       if (!pte_present(pte))
+               goto out;
+       if (write && !pte_write(pte))
+               goto out;
+       page = pte_page(pte);
+       if (!VALID_PAGE(page)) {
+               page = NULL;
+               goto out;
+       }
+
+       /* Increment reference count on page */
+       get_page(page);
+
+out:
+       spin_unlock(&init_mm.page_table_lock);
+
+       return page;
+}
+
+struct vm_operations_struct kmem_vm_ops = {
+       nopage:         kmem_vm_nopage,
+};
+
+static int mmap_kmem(struct file * file, struct vm_area_struct * vma)
+{
+       unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+       unsigned long size = vma->vm_end - vma->vm_start;
+
+#if defined(CONFIG_XENO)
+       return -ENXIO;
+#endif
+
+       /*
+        * If the user is not attempting to mmap a high memory address then
+        * the standard mmap_mem mechanism will work.  High memory addresses
+        * need special handling, as remap_page_range expects a physically-
+        * contiguous range of kernel addresses (such as obtained in kmalloc).
+        */
+       if ((offset + size) < (unsigned long) high_memory)
+               return mmap_mem(file, vma);
+
+       /*
+        * Accessing memory above the top the kernel knows about or
+        * through a file pointer that was marked O_SYNC will be
+        * done non-cached.
+        */
+       if (noncached_address(offset) || (file->f_flags & O_SYNC))
+               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+       /* Don't do anything here; "nopage" will fill the holes */
+       vma->vm_ops = &kmem_vm_ops;
+
+       /* Don't try to swap out physical pages.. */
+       vma->vm_flags |= VM_RESERVED;
+
+       /*
+        * Don't dump addresses that are not real memory to a core file.
+        */
+       vma->vm_flags |= VM_IO;
+
+       return 0;
+}
+
+#define zero_lseek     null_lseek
+#define full_lseek      null_lseek
+#define write_zero     write_null
+#define read_full       read_zero
+#define open_mem       open_port
+#define open_kmem      open_mem
+
+static struct file_operations mem_fops = {
+       llseek:         memory_lseek,
+       read:           read_mem,
+       write:          write_mem,
+       mmap:           mmap_mem,
+       open:           open_mem,
+};
+
+static struct file_operations kmem_fops = {
+       llseek:         memory_lseek,
+       read:           read_kmem,
+       write:          write_kmem,
+       mmap:           mmap_kmem,
+       open:           open_kmem,
+};
+
+static struct file_operations null_fops = {
+       llseek:         null_lseek,
+       read:           read_null,
+       write:          write_null,
+};
+
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
+static struct file_operations port_fops = {
+       llseek:         memory_lseek,
+       read:           read_port,
+       write:          write_port,
+       open:           open_port,
+};
+#endif
+
+static struct file_operations zero_fops = {
+       llseek:         zero_lseek,
+       read:           read_zero,
+       write:          write_zero,
+       mmap:           mmap_zero,
+};
+
+static struct file_operations full_fops = {
+       llseek:         full_lseek,
+       read:           read_full,
+       write:          write_full,
+};
+
+static int memory_open(struct inode * inode, struct file * filp)
+{
+       switch (MINOR(inode->i_rdev)) {
+               case 1:
+                       filp->f_op = &mem_fops;
+                       break;
+               case 2:
+                       filp->f_op = &kmem_fops;
+                       break;
+               case 3:
+                       filp->f_op = &null_fops;
+                       break;
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
+               case 4:
+#if defined(CONFIG_XENO)
+#if defined(CONFIG_XENO_PRIV)
+                       if (!(start_info.flags & SIF_PRIVILEGED))
+#endif
+                               return -ENXIO;
+#endif
+                       filp->f_op = &port_fops;
+                       break;
+#endif
+               case 5:
+                       filp->f_op = &zero_fops;
+                       break;
+               case 7:
+                       filp->f_op = &full_fops;
+                       break;
+               case 8:
+                       filp->f_op = &random_fops;
+                       break;
+               case 9:
+                       filp->f_op = &urandom_fops;
+                       break;
+               default:
+                       return -ENXIO;
+       }
+       if (filp->f_op && filp->f_op->open)
+               return filp->f_op->open(inode,filp);
+       return 0;
+}
+
+void __init memory_devfs_register (void)
+{
+    /*  These are never unregistered  */
+    static const struct {
+       unsigned short minor;
+       char *name;
+       umode_t mode;
+       struct file_operations *fops;
+    } list[] = { /* list of minor devices */
+       {1, "mem",     S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
+       {2, "kmem",    S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
+       {3, "null",    S_IRUGO | S_IWUGO,           &null_fops},
+#if defined(CONFIG_ISA) || !defined(__mc68000__)
+       {4, "port",    S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
+#endif
+       {5, "zero",    S_IRUGO | S_IWUGO,           &zero_fops},
+       {7, "full",    S_IRUGO | S_IWUGO,           &full_fops},
+       {8, "random",  S_IRUGO | S_IWUSR,           &random_fops},
+       {9, "urandom", S_IRUGO | S_IWUSR,           &urandom_fops}
+    };
+    int i;
+
+    for (i=0; i<(sizeof(list)/sizeof(*list)); i++)
+       devfs_register (NULL, list[i].name, DEVFS_FL_NONE,
+                       MEM_MAJOR, list[i].minor,
+                       list[i].mode | S_IFCHR,
+                       list[i].fops, NULL);
+}
+
+static struct file_operations memory_fops = {
+       open:           memory_open,    /* just a selector for the real open */
+};
+
+int __init chr_dev_init(void)
+{
+       if (devfs_register_chrdev(MEM_MAJOR,"mem",&memory_fops))
+               printk("unable to get major %d for memory devs\n", MEM_MAJOR);
+       memory_devfs_register();
+       rand_initialize();
+#ifdef CONFIG_I2C
+       i2c_init_all();
+#endif
+#if defined (CONFIG_FB)
+       fbmem_init();
+#endif
+#if defined (CONFIG_PROM_CONSOLE)
+       prom_con_init();
+#endif
+#if defined (CONFIG_MDA_CONSOLE)
+       mda_console_init();
+#endif
+       tty_init();
+#ifdef CONFIG_M68K_PRINTER
+       lp_m68k_init();
+#endif
+       misc_init();
+#if CONFIG_QIC02_TAPE
+       qic02_tape_init();
+#endif
+#ifdef CONFIG_FTAPE
+       ftape_init();
+#endif
+#if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR)
+       tapechar_init();
+#endif
+       return 0;
+}
+
+__initcall(chr_dev_init);
diff --git a/xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h b/xenolinux-2.4.21-sparse/include/asm-xeno/dom0.h
deleted file mode 100644 (file)
index 6609be0..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/* IOCTLs used when access /proc/xeno/dom0_cmd. */
-#ifndef __DOM0_H__
-#define __DOM0_H__
-
-#define IOCTL_DOM0_CREATEDOMAIN _IOC(_IOC_READ, 'x', 0, sizeof(struct dom0_createdomain_args))
-#define IOCTL_DOM0_MAPDOMMEM _IOC(_IOC_READ, 'x', 1, sizeof(struct dom0_mapdommem_args))
-#define IOCTL_DOM0_UNMAPDOMMEM _IOC(_IOC_READ, 'x', 2, sizeof(struct dom0_unmapdommem_args))
-#define IOCTL_DOM0_DOPGUPDATES _IOC(_IOC_READ, 'x', 3, sizeof(struct dom0_dopgupdates_args))
-
-struct dom0_createdomain_args
-{
-    unsigned int kb_mem;
-    const char *name;
-};
-
-struct dom0_mapdommem_args
-{
-    unsigned int domain;
-    unsigned start_pfn;
-    unsigned tot_pages;  
-};
-
-struct dom0_unmapdommem_args
-{
-    unsigned long vaddr;
-    unsigned long start_pfn;
-    unsigned long tot_pages;
-};
-
-struct dom0_dopgupdates_args
-{
-    unsigned long pgt_update_arr;
-    unsigned long num_pgt_updates;
-};
-
-#endif /* __DOM0_H__ */
index abf109b2cacdba55b4e18556a412ecc972a137f0..751bdc7888e4139afe1a8d759376c948a7a1b871 100644 (file)
@@ -9,9 +9,9 @@
 #ifndef __HYPERVISOR_H__
 #define __HYPERVISOR_H__
 
+#include <linux/types.h>
 #include <asm/hypervisor-ifs/hypervisor-if.h>
 #include <asm/ptrace.h>
-//#include <asm/page.h>
 
 /* arch/xeno/kernel/setup.c */
 union start_info_union
diff --git a/xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h b/xenolinux-2.4.21-sparse/include/asm-xeno/mmu.h
deleted file mode 100644 (file)
index b7bc05d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef __i386_MMU_H
-#define __i386_MMU_H
-
-#include <linux/list.h>
-
-/* describes dirrectly mapped vma nodes */
-typedef struct {
-    struct list_head list;
-    unsigned long vm_start;
-       unsigned long vm_end;
-} direct_mmap_node_t;
-
-/*
- * The i386 doesn't have a mmu context, but
- * we put the segment information here.
- */
-typedef struct { 
-       void *segments;
-       unsigned long cpuvalid;
-    struct list_head direct_list;
-} mm_context_t;
-
-#endif
index 83514ebd14d9201aa8201c1aa502b9611ccc1ab5..1eab441990884e14a24317b25c53c0e06d6fd318 100644 (file)
@@ -5,15 +5,12 @@
 #include <asm/desc.h>
 #include <asm/atomic.h>
 #include <asm/pgalloc.h>
-#include <asm/multicall.h>
-
-/* Hooked directly from 'init_new_context'. */
-extern int init_direct_list(struct mm_struct *);
-/* Called from 'release_segments'. */
-extern void destroy_direct_list(struct mm_struct *);
 
+/*
+ * possibly do the LDT unload here?
+ */
 #define destroy_context(mm)            do { } while(0)
-#define init_new_context(tsk,mm)       init_direct_list(mm)
+#define init_new_context(tsk,mm)       0
 
 #ifdef CONFIG_SMP
 
index 27126dcaac55e8415e309b714347293ebdb601f8..f0ea5c3a6623324ed0bda45e7015e0b24a7ecdb4 100644 (file)
@@ -35,6 +35,45 @@ static inline void queue_multicall2(
     nr_multicall_ents = i+1;
 }
 
+static inline void queue_multicall3(
+    unsigned long op, unsigned long arg1, unsigned long arg2,
+    unsigned long arg3)
+{
+    int i = nr_multicall_ents;
+    multicall_list[i].op      = op;
+    multicall_list[i].args[0] = arg1;
+    multicall_list[i].args[1] = arg2;
+    multicall_list[i].args[2] = arg3;
+    nr_multicall_ents = i+1;
+}
+
+static inline void queue_multicall4(
+    unsigned long op, unsigned long arg1, unsigned long arg2,
+    unsigned long arg3, unsigned long arg4)
+{
+    int i = nr_multicall_ents;
+    multicall_list[i].op      = op;
+    multicall_list[i].args[0] = arg1;
+    multicall_list[i].args[1] = arg2;
+    multicall_list[i].args[2] = arg3;
+    multicall_list[i].args[3] = arg4;
+    nr_multicall_ents = i+1;
+}
+
+static inline void queue_multicall5(
+    unsigned long op, unsigned long arg1, unsigned long arg2,
+    unsigned long arg3, unsigned long arg4, unsigned long arg5)
+{
+    int i = nr_multicall_ents;
+    multicall_list[i].op      = op;
+    multicall_list[i].args[0] = arg1;
+    multicall_list[i].args[1] = arg2;
+    multicall_list[i].args[2] = arg3;
+    multicall_list[i].args[3] = arg4;
+    multicall_list[i].args[4] = arg5;
+    nr_multicall_ents = i+1;
+}
+
 static inline void execute_multicall_list(void)
 {
     if ( unlikely(nr_multicall_ents == 0) ) return;
index 49d6e30b2a92bba5fe5caed0481ba9d255cd3ae4..0f502cfcb8ca7855e6984d0051580a9baa6ed79d 100644 (file)
@@ -265,4 +265,10 @@ static inline void flush_tlb_pgtables(struct mm_struct *mm,
     XENO_flush_page_update_queue();
 }
 
+extern int direct_remap_area_pages(struct mm_struct *mm,
+                                   unsigned long address, 
+                                   unsigned long machine_addr,
+                                   unsigned long size, 
+                                   pgprot_t prot);
+
 #endif /* _I386_PGALLOC_H */
index 0f914c7c424f212fcb96b2b0c72500f3dbd872dc..0a2482f96fb12a5e0d9bea386720e556deaf907d 100644 (file)
@@ -3,8 +3,6 @@
 
 #include <linux/config.h>
 
-#define HAVE_ARCH_UNMAPPED_AREA
-
 /*
  * The Linux memory management assumes a three-level page table setup. On
  * the i386, we use that, but "fold" the mid level into the top-level page
@@ -114,6 +112,7 @@ extern void * high_memory;
 #define _PAGE_BIT_DIRTY                6
 #define _PAGE_BIT_PSE          7       /* 4 MB (or 2MB) page, Pentium+, if present.. */
 #define _PAGE_BIT_GLOBAL       8       /* Global TLB entry PPro+ */
+#define _PAGE_BIT_IO            9
 
 #define _PAGE_PRESENT  0x001
 #define _PAGE_RW       0x002
@@ -124,6 +123,7 @@ extern void * high_memory;
 #define _PAGE_DIRTY    0x040
 #define _PAGE_PSE      0x080   /* 4 MB (or 2MB) page, Pentium+, if present.. */
 #define _PAGE_GLOBAL   0x100   /* Global TLB entry PPro+ */
+#define _PAGE_IO        0x200
 
 #define _PAGE_PROTNONE 0x080   /* If not present */
 
@@ -196,6 +196,7 @@ static inline int pte_exec(pte_t pte)               { return (pte).pte_low & _PAGE_USER; }
 static inline int pte_dirty(pte_t pte)         { return (pte).pte_low & _PAGE_DIRTY; }
 static inline int pte_young(pte_t pte)         { return (pte).pte_low & _PAGE_ACCESSED; }
 static inline int pte_write(pte_t pte)         { return (pte).pte_low & _PAGE_RW; }
+static inline int pte_io(pte_t pte)            { return (pte).pte_low & _PAGE_IO; }
 
 static inline pte_t pte_rdprotect(pte_t pte)   { (pte).pte_low &= ~_PAGE_USER; return pte; }
 static inline pte_t pte_exprotect(pte_t pte)   { (pte).pte_low &= ~_PAGE_USER; return pte; }
@@ -207,6 +208,7 @@ static inline pte_t pte_mkexec(pte_t pte)   { (pte).pte_low |= _PAGE_USER; return
 static inline pte_t pte_mkdirty(pte_t pte)     { (pte).pte_low |= _PAGE_DIRTY; return pte; }
 static inline pte_t pte_mkyoung(pte_t pte)     { (pte).pte_low |= _PAGE_ACCESSED; return pte; }
 static inline pte_t pte_mkwrite(pte_t pte)     { (pte).pte_low |= _PAGE_RW; return pte; }
+static inline pte_t pte_mkio(pte_t pte)                { (pte).pte_low |= _PAGE_IO; return pte; }
 
 static inline int ptep_test_and_clear_dirty(pte_t *ptep)
 {
diff --git a/xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h b/xenolinux-2.4.21-sparse/include/asm-xeno/proc_cmd.h
new file mode 100644 (file)
index 0000000..89386f4
--- /dev/null
@@ -0,0 +1,28 @@
+/******************************************************************************
+ * proc_cmd.h
+ * 
+ * Interface to /proc/cmd and /proc/xeno/privcmd.
+ */
+
+#ifndef __PROC_CMD_H__
+#define __PROC_CMD_H__
+
+#define IOCTL_PRIVCMD_HYPERCALL        0
+#define IOCTL_PRIVCMD_BLKMSG           1
+#define IOCTL_PRIVCMD_LINDEV_TO_XENDEV 2
+#define IOCTL_PRIVCMD_XENDEV_TO_LINDEV 3
+
+typedef struct privcmd_hypercall
+{
+    unsigned long op;
+    unsigned long arg[5];
+} privcmd_hypercall_t;
+
+typedef struct privcmd_blkmsg
+{
+    unsigned long op;
+    void         *buf;
+    int           buf_size;
+} privcmd_blkmsg_t;
+
+#endif /* __PROC_CMD_H__ */
index 35862eb1f28b806109ead00b73b0aa83c9b5f2b5..ca13028ce01f9090453f17f263d38366a9d5467c 100644 (file)
@@ -1,6 +1,9 @@
 #ifndef _ASM_SEGMENT_H
 #define _ASM_SEGMENT_H
 
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#endif
 #include <asm/hypervisor-ifs/hypervisor-if.h>
 
 #define __KERNEL_CS    FLAT_RING1_CS
index 8c02e17f1e7a9c0129292cb89028c0c4a434f421..ffb7fde4fa1d4352f66faab780c56e833cc6f31d 100755 (executable)
@@ -125,6 +125,7 @@ ln -sf ../asm-i386/math_emu.h
 ln -sf ../asm-i386/mc146818rtc.h
 ln -sf ../asm-i386/mca_dma.h 
 ln -sf ../asm-i386/mman.h 
+ln -sf ../asm-i386/mmu.h 
 ln -sf ../asm-i386/mmx.h 
 ln -sf ../asm-i386/module.h 
 ln -sf ../asm-i386/mpspec.h 
index 0c6d000e1f64b01dc27ef200560af43d5794ecf3..d3833e4bf36d6c462b965f936e838cb6ecbe2d21 100644 (file)
@@ -318,6 +318,13 @@ static inline int zap_pte_range(mmu_gather_t *tlb, pmd_t * pmd, unsigned long ad
                        continue;
                if (pte_present(pte)) {
                        struct page *page = pte_page(pte);
+#if defined(CONFIG_XENO_PRIV)
+                       if (pte_io(pte)) {
+                               queue_l1_entry_update(
+                                       __pa(ptep)|PGREQ_UNCHECKED_UPDATE, 0);
+                               continue;
+                       }
+#endif
                        if (VALID_PAGE(page) && !PageReserved(page))
                                freed ++;
                        /* This will eventually call __free_pte on the pte. */
@@ -1374,6 +1381,15 @@ int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct * vma,
        pgd_t *pgd;
        pmd_t *pmd;
 
+#if defined(CONFIG_XENO_PRIV)
+       /* Take care of I/O mappings right here. */
+       if (vma->vm_flags & VM_IO) {
+               if (write_access && !(vma->vm_flags & VM_WRITE))
+                       return -1;
+               return 1;
+       }
+#endif
+
        current->state = TASK_RUNNING;
        pgd = pgd_offset(mm, address);
 
diff --git a/xenolinux-2.4.21-sparse/mm/mprotect.c b/xenolinux-2.4.21-sparse/mm/mprotect.c
new file mode 100644 (file)
index 0000000..a6f355d
--- /dev/null
@@ -0,0 +1,344 @@
+/*
+ *     linux/mm/mprotect.c
+ *
+ *  (C) Copyright 1994 Linus Torvalds
+ */
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/shm.h>
+#include <linux/mman.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+static inline void change_pte_range(pmd_t * pmd, unsigned long address,
+       unsigned long size, pgprot_t newprot)
+{
+       pte_t * pte;
+       unsigned long end;
+
+       if (pmd_none(*pmd))
+               return;
+       if (pmd_bad(*pmd)) {
+               pmd_ERROR(*pmd);
+               pmd_clear(pmd);
+               return;
+       }
+       pte = pte_offset(pmd, address);
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               if (pte_present(*pte)) {
+                       pte_t entry;
+
+                       /* Avoid an SMP race with hardware updated dirty/clean
+                        * bits by wiping the pte and then setting the new pte
+                        * into place.
+                        */
+                       entry = ptep_get_and_clear(pte);
+                       set_pte(pte, pte_modify(entry, newprot));
+               }
+               address += PAGE_SIZE;
+               pte++;
+       } while (address && (address < end));
+}
+
+static inline void change_pmd_range(pgd_t * pgd, unsigned long address,
+       unsigned long size, pgprot_t newprot)
+{
+       pmd_t * pmd;
+       unsigned long end;
+
+       if (pgd_none(*pgd))
+               return;
+       if (pgd_bad(*pgd)) {
+               pgd_ERROR(*pgd);
+               pgd_clear(pgd);
+               return;
+       }
+       pmd = pmd_offset(pgd, address);
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       do {
+               change_pte_range(pmd, address, end - address, newprot);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address && (address < end));
+}
+
+static void change_protection(unsigned long start, unsigned long end, pgprot_t newprot)
+{
+       pgd_t *dir;
+       unsigned long beg = start;
+
+       dir = pgd_offset(current->mm, start);
+       flush_cache_range(current->mm, beg, end);
+       if (start >= end)
+               BUG();
+       spin_lock(&current->mm->page_table_lock);
+       do {
+               change_pmd_range(dir, start, end - start, newprot);
+               start = (start + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       } while (start && (start < end));
+       spin_unlock(&current->mm->page_table_lock);
+       flush_tlb_range(current->mm, beg, end);
+       return;
+}
+
+static inline int mprotect_fixup_all(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
+       int newflags, pgprot_t prot)
+{
+       struct vm_area_struct * prev = *pprev;
+       struct mm_struct * mm = vma->vm_mm;
+
+       if (prev && prev->vm_end == vma->vm_start && can_vma_merge(prev, newflags) &&
+           !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+               spin_lock(&mm->page_table_lock);
+               prev->vm_end = vma->vm_end;
+               __vma_unlink(mm, vma, prev);
+               spin_unlock(&mm->page_table_lock);
+
+               kmem_cache_free(vm_area_cachep, vma);
+               mm->map_count--;
+
+               return 0;
+       }
+
+       spin_lock(&mm->page_table_lock);
+       vma->vm_flags = newflags;
+       vma->vm_page_prot = prot;
+       spin_unlock(&mm->page_table_lock);
+
+       *pprev = vma;
+
+       return 0;
+}
+
+static inline int mprotect_fixup_start(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
+       unsigned long end,
+       int newflags, pgprot_t prot)
+{
+       struct vm_area_struct * n, * prev = *pprev;
+
+       *pprev = vma;
+
+       if (prev && prev->vm_end == vma->vm_start && can_vma_merge(prev, newflags) &&
+           !vma->vm_file && !(vma->vm_flags & VM_SHARED)) {
+               spin_lock(&vma->vm_mm->page_table_lock);
+               prev->vm_end = end;
+               vma->vm_start = end;
+               spin_unlock(&vma->vm_mm->page_table_lock);
+
+               return 0;
+       }
+       n = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+       if (!n)
+               return -ENOMEM;
+       *n = *vma;
+       n->vm_end = end;
+       n->vm_flags = newflags;
+       n->vm_raend = 0;
+       n->vm_page_prot = prot;
+       if (n->vm_file)
+               get_file(n->vm_file);
+       if (n->vm_ops && n->vm_ops->open)
+               n->vm_ops->open(n);
+       vma->vm_pgoff += (end - vma->vm_start) >> PAGE_SHIFT;
+       lock_vma_mappings(vma);
+       spin_lock(&vma->vm_mm->page_table_lock);
+       vma->vm_start = end;
+       __insert_vm_struct(current->mm, n);
+       spin_unlock(&vma->vm_mm->page_table_lock);
+       unlock_vma_mappings(vma);
+
+       return 0;
+}
+
+static inline int mprotect_fixup_end(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
+       unsigned long start,
+       int newflags, pgprot_t prot)
+{
+       struct vm_area_struct * n;
+
+       n = kmem_cache_alloc(vm_area_cachep, GFP_KERNEL);
+       if (!n)
+               return -ENOMEM;
+       *n = *vma;
+       n->vm_start = start;
+       n->vm_pgoff += (n->vm_start - vma->vm_start) >> PAGE_SHIFT;
+       n->vm_flags = newflags;
+       n->vm_raend = 0;
+       n->vm_page_prot = prot;
+       if (n->vm_file)
+               get_file(n->vm_file);
+       if (n->vm_ops && n->vm_ops->open)
+               n->vm_ops->open(n);
+       lock_vma_mappings(vma);
+       spin_lock(&vma->vm_mm->page_table_lock);
+       vma->vm_end = start;
+       __insert_vm_struct(current->mm, n);
+       spin_unlock(&vma->vm_mm->page_table_lock);
+       unlock_vma_mappings(vma);
+
+       *pprev = n;
+
+       return 0;
+}
+
+static inline int mprotect_fixup_middle(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
+       unsigned long start, unsigned long end,
+       int newflags, pgprot_t prot)
+{
+       struct vm_area_struct * left, * right;
+
+       left = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+       if (!left)
+               return -ENOMEM;
+       right = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
+       if (!right) {
+               kmem_cache_free(vm_area_cachep, left);
+               return -ENOMEM;
+       }
+       *left = *vma;
+       *right = *vma;
+       left->vm_end = start;
+       right->vm_start = end;
+       right->vm_pgoff += (right->vm_start - left->vm_start) >> PAGE_SHIFT;
+       left->vm_raend = 0;
+       right->vm_raend = 0;
+       if (vma->vm_file)
+               atomic_add(2,&vma->vm_file->f_count);
+       if (vma->vm_ops && vma->vm_ops->open) {
+               vma->vm_ops->open(left);
+               vma->vm_ops->open(right);
+       }
+       vma->vm_pgoff += (start - vma->vm_start) >> PAGE_SHIFT;
+       vma->vm_raend = 0;
+       vma->vm_page_prot = prot;
+       lock_vma_mappings(vma);
+       spin_lock(&vma->vm_mm->page_table_lock);
+       vma->vm_start = start;
+       vma->vm_end = end;
+       vma->vm_flags = newflags;
+       __insert_vm_struct(current->mm, left);
+       __insert_vm_struct(current->mm, right);
+       spin_unlock(&vma->vm_mm->page_table_lock);
+       unlock_vma_mappings(vma);
+
+       *pprev = right;
+
+       return 0;
+}
+
+static int mprotect_fixup(struct vm_area_struct * vma, struct vm_area_struct ** pprev,
+       unsigned long start, unsigned long end, unsigned int newflags)
+{
+       pgprot_t newprot;
+       int error;
+
+       if (newflags == vma->vm_flags) {
+               *pprev = vma;
+               return 0;
+       }
+       newprot = protection_map[newflags & 0xf];
+       if (start == vma->vm_start) {
+               if (end == vma->vm_end)
+                       error = mprotect_fixup_all(vma, pprev, newflags, newprot);
+               else
+                       error = mprotect_fixup_start(vma, pprev, end, newflags, newprot);
+       } else if (end == vma->vm_end)
+               error = mprotect_fixup_end(vma, pprev, start, newflags, newprot);
+       else
+               error = mprotect_fixup_middle(vma, pprev, start, end, newflags, newprot);
+
+       if (error)
+               return error;
+
+       change_protection(start, end, newprot);
+       return 0;
+}
+
+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
+{
+       unsigned long nstart, end, tmp;
+       struct vm_area_struct * vma, * next, * prev;
+       int error = -EINVAL;
+
+       if (start & ~PAGE_MASK)
+               return -EINVAL;
+       len = PAGE_ALIGN(len);
+       end = start + len;
+       if (end < start)
+               return -EINVAL;
+       if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+               return -EINVAL;
+       if (end == start)
+               return 0;
+
+       down_write(&current->mm->mmap_sem);
+
+       vma = find_vma_prev(current->mm, start, &prev);
+       error = -ENOMEM;
+       if (!vma || vma->vm_start > start)
+               goto out;
+
+#if defined(CONFIG_XENO_PRIV)
+       /* mprotect() unsupported for I/O mappings in Xenolinux. */
+       error = -EINVAL;
+       if (vma->vm_flags & VM_IO)
+               goto out;
+#endif
+
+       for (nstart = start ; ; ) {
+               unsigned int newflags;
+               int last = 0;
+
+               /* Here we know that  vma->vm_start <= nstart < vma->vm_end. */
+
+               newflags = prot | (vma->vm_flags & ~(PROT_READ | PROT_WRITE | PROT_EXEC));
+               if ((newflags & ~(newflags >> 4)) & 0xf) {
+                       error = -EACCES;
+                       goto out;
+               }
+
+               if (vma->vm_end > end) {
+                       error = mprotect_fixup(vma, &prev, nstart, end, newflags);
+                       goto out;
+               }
+               if (vma->vm_end == end)
+                       last = 1;
+
+               tmp = vma->vm_end;
+               next = vma->vm_next;
+               error = mprotect_fixup(vma, &prev, nstart, tmp, newflags);
+               if (error)
+                       goto out;
+               if (last)
+                       break;
+               nstart = tmp;
+               vma = next;
+               if (!vma || vma->vm_start != nstart) {
+                       error = -ENOMEM;
+                       goto out;
+               }
+       }
+       if (next && prev->vm_end == next->vm_start && can_vma_merge(next, prev->vm_flags) &&
+           !prev->vm_file && !(prev->vm_flags & VM_SHARED)) {
+               spin_lock(&prev->vm_mm->page_table_lock);
+               prev->vm_end = next->vm_end;
+               __vma_unlink(prev->vm_mm, next, prev);
+               spin_unlock(&prev->vm_mm->page_table_lock);
+
+               kmem_cache_free(vm_area_cachep, next);
+               prev->vm_mm->map_count--;
+       }
+out:
+       up_write(&current->mm->mmap_sem);
+       return error;
+}
index a2e0d860dd8cffa1f4573432137e4b26dae1604b..a452b467f73add947fd6418af855b376def62932 100644 (file)
@@ -293,6 +293,13 @@ unsigned long do_mremap(unsigned long addr,
            !vm_enough_memory((new_len - old_len) >> PAGE_SHIFT))
                goto out;
 
+#if defined(CONFIG_XENO_PRIV)
+       /* mremap() unsupported for I/O mappings in Xenolinux. */
+       ret = -EINVAL;
+       if (vma->vm_flags & VM_IO)
+               goto out;
+#endif
+
        /* old_len exactly to the end of the area..
         * And we're not relocating the area.
         */
diff --git a/xenolinux-2.4.21-sparse/mm/vmalloc.c b/xenolinux-2.4.21-sparse/mm/vmalloc.c
new file mode 100644 (file)
index 0000000..015cad0
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ *  linux/mm/vmalloc.c
+ *
+ *  Copyright (C) 1993  Linus Torvalds
+ *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
+ *  SMP-safe vmalloc/vfree/ioremap, Tigran Aivazian <tigran@veritas.com>, May 2000
+ */
+
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/spinlock.h>
+#include <linux/highmem.h>
+#include <linux/smp_lock.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgalloc.h>
+
+rwlock_t vmlist_lock = RW_LOCK_UNLOCKED;
+struct vm_struct * vmlist;
+
+static inline void free_area_pte(pmd_t * pmd, unsigned long address, unsigned long size)
+{
+       pte_t * pte;
+       unsigned long end;
+
+       if (pmd_none(*pmd))
+               return;
+       if (pmd_bad(*pmd)) {
+               pmd_ERROR(*pmd);
+               pmd_clear(pmd);
+               return;
+       }
+       pte = pte_offset(pmd, address);
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               pte_t page;
+               page = ptep_get_and_clear(pte);
+               address += PAGE_SIZE;
+               pte++;
+               if (pte_none(page))
+                       continue;
+               if (pte_present(page)) {
+                       struct page *ptpage = pte_page(page);
+                       if (VALID_PAGE(ptpage) && (!PageReserved(ptpage)))
+                               __free_page(ptpage);
+                       continue;
+               }
+               printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n");
+       } while (address < end);
+}
+
+static inline void free_area_pmd(pgd_t * dir, unsigned long address, unsigned long size)
+{
+       pmd_t * pmd;
+       unsigned long end;
+
+       if (pgd_none(*dir))
+               return;
+       if (pgd_bad(*dir)) {
+               pgd_ERROR(*dir);
+               pgd_clear(dir);
+               return;
+       }
+       pmd = pmd_offset(dir, address);
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       do {
+               free_area_pte(pmd, address, end - address);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address < end);
+}
+
+void vmfree_area_pages(unsigned long address, unsigned long size)
+{
+       pgd_t * dir;
+       unsigned long end = address + size;
+
+       dir = pgd_offset_k(address);
+       flush_cache_all();
+       do {
+               free_area_pmd(dir, address, end - address);
+               address = (address + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       } while (address && (address < end));
+       flush_tlb_all();
+}
+
+static inline int alloc_area_pte (pte_t * pte, unsigned long address,
+                       unsigned long size, int gfp_mask, pgprot_t prot)
+{
+       unsigned long end;
+
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               struct page * page;
+               spin_unlock(&init_mm.page_table_lock);
+               page = alloc_page(gfp_mask);
+               spin_lock(&init_mm.page_table_lock);
+               if (!pte_none(*pte))
+                       printk(KERN_ERR "alloc_area_pte: page already exists\n");
+               if (!page)
+                       return -ENOMEM;
+               set_pte(pte, mk_pte(page, prot));
+               address += PAGE_SIZE;
+               pte++;
+       } while (address < end);
+       return 0;
+}
+
+static inline int alloc_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, int gfp_mask, pgprot_t prot)
+{
+       unsigned long end;
+
+       address &= ~PGDIR_MASK;
+       end = address + size;
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+       do {
+               pte_t * pte = pte_alloc(&init_mm, pmd, address);
+               if (!pte)
+                       return -ENOMEM;
+               if (alloc_area_pte(pte, address, end - address, gfp_mask, prot))
+                       return -ENOMEM;
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address < end);
+       return 0;
+}
+
+inline int vmalloc_area_pages (unsigned long address, unsigned long size,
+                               int gfp_mask, pgprot_t prot)
+{
+       pgd_t * dir;
+       unsigned long end = address + size;
+       int ret;
+
+       dir = pgd_offset_k(address);
+       spin_lock(&init_mm.page_table_lock);
+       do {
+               pmd_t *pmd;
+               
+               pmd = pmd_alloc(&init_mm, dir, address);
+               ret = -ENOMEM;
+               if (!pmd)
+                       break;
+
+               ret = -ENOMEM;
+               if (alloc_area_pmd(pmd, address, end - address, gfp_mask, prot))
+                       break;
+
+               address = (address + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+
+               ret = 0;
+       } while (address && (address < end));
+       spin_unlock(&init_mm.page_table_lock);
+       flush_cache_all();
+       return ret;
+}
+
+struct vm_struct * get_vm_area(unsigned long size, unsigned long flags)
+{
+       unsigned long addr, next;
+       struct vm_struct **p, *tmp, *area;
+
+       area = (struct vm_struct *) kmalloc(sizeof(*area), GFP_KERNEL);
+       if (!area)
+               return NULL;
+
+       size += PAGE_SIZE;
+       if (!size) {
+               kfree (area);
+               return NULL;
+       }
+
+       addr = VMALLOC_START;
+       write_lock(&vmlist_lock);
+       for (p = &vmlist; (tmp = *p) ; p = &tmp->next) {
+               if ((size + addr) < addr)
+                       goto out;
+               if (size + addr <= (unsigned long) tmp->addr)
+                       break;
+               next = tmp->size + (unsigned long) tmp->addr;
+               if (next > addr) 
+                       addr = next;
+               if (addr > VMALLOC_END-size)
+                       goto out;
+       }
+       area->flags = flags;
+       area->addr = (void *)addr;
+       area->size = size;
+       area->next = *p;
+       *p = area;
+       write_unlock(&vmlist_lock);
+       return area;
+
+out:
+       write_unlock(&vmlist_lock);
+       kfree(area);
+       return NULL;
+}
+
+void vfree(void * addr)
+{
+       struct vm_struct **p, *tmp;
+
+       if (!addr)
+               return;
+       if ((PAGE_SIZE-1) & (unsigned long) addr) {
+               printk(KERN_ERR "Trying to vfree() bad address (%p)\n", addr);
+               return;
+       }
+       write_lock(&vmlist_lock);
+       for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
+               if (tmp->addr == addr) {
+                       *p = tmp->next;
+#ifdef CONFIG_XENO_PRIV
+                       if (tmp->flags & VM_IOREMAP)
+                               zap_page_range(&init_mm, VMALLOC_VMADDR(tmp->addr), tmp->size);
+                       else
+#endif
+                       vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
+                       write_unlock(&vmlist_lock);
+                       kfree(tmp);
+                       return;
+               }
+       }
+       write_unlock(&vmlist_lock);
+       printk(KERN_ERR "Trying to vfree() nonexistent vm area (%p)\n", addr);
+}
+
+void * __vmalloc (unsigned long size, int gfp_mask, pgprot_t prot)
+{
+       void * addr;
+       struct vm_struct *area;
+
+       size = PAGE_ALIGN(size);
+       if (!size || (size >> PAGE_SHIFT) > num_physpages)
+               return NULL;
+       area = get_vm_area(size, VM_ALLOC);
+       if (!area)
+               return NULL;
+       addr = area->addr;
+       if (vmalloc_area_pages(VMALLOC_VMADDR(addr), size, gfp_mask, prot)) {
+               vfree(addr);
+               return NULL;
+       }
+       return addr;
+}
+
+long vread(char *buf, char *addr, unsigned long count)
+{
+       struct vm_struct *tmp;
+       char *vaddr, *buf_start = buf;
+       unsigned long n;
+
+       /* Don't allow overflow */
+       if ((unsigned long) addr + count < count)
+               count = -(unsigned long) addr;
+
+       read_lock(&vmlist_lock);
+       for (tmp = vmlist; tmp; tmp = tmp->next) {
+               vaddr = (char *) tmp->addr;
+               if (addr >= vaddr + tmp->size - PAGE_SIZE)
+                       continue;
+               while (addr < vaddr) {
+                       if (count == 0)
+                               goto finished;
+                       *buf = '\0';
+                       buf++;
+                       addr++;
+                       count--;
+               }
+               n = vaddr + tmp->size - PAGE_SIZE - addr;
+               do {
+                       if (count == 0)
+                               goto finished;
+                       *buf = *addr;
+                       buf++;
+                       addr++;
+                       count--;
+               } while (--n > 0);
+       }
+finished:
+       read_unlock(&vmlist_lock);
+       return buf - buf_start;
+}
+
+long vwrite(char *buf, char *addr, unsigned long count)
+{
+       struct vm_struct *tmp;
+       char *vaddr, *buf_start = buf;
+       unsigned long n;
+
+       /* Don't allow overflow */
+       if ((unsigned long) addr + count < count)
+               count = -(unsigned long) addr;
+
+       read_lock(&vmlist_lock);
+       for (tmp = vmlist; tmp; tmp = tmp->next) {
+               vaddr = (char *) tmp->addr;
+               if (addr >= vaddr + tmp->size - PAGE_SIZE)
+                       continue;
+               while (addr < vaddr) {
+                       if (count == 0)
+                               goto finished;
+                       buf++;
+                       addr++;
+                       count--;
+               }
+               n = vaddr + tmp->size - PAGE_SIZE - addr;
+               do {
+                       if (count == 0)
+                               goto finished;
+                       *addr = *buf;
+                       buf++;
+                       addr++;
+                       count--;
+               } while (--n > 0);
+       }
+finished:
+       read_unlock(&vmlist_lock);
+       return buf - buf_start;
+}